Profile picture

[Linux] Xargs 명령어 정리

JaehyoJJAng2023년 03월 15일

Xargs 옵션

옵션 의미
-O 공백이나 특수문자를 찾을 때 사용
-print0 파일 사이의 공백을 \0으로 분리자로 출력하고 xargs에서는 \0으로 표시된 분리자를 인식하여 하나의 파일이름으로 인식하고 다음 인자로 넘어감
-I(i) xargs에 전달된 라인 전체를 뒤에 나오는 명령어의 인자로 사용 (디폴트로 라인 전체를 의미하는 기호는 {} 임)

xargs 명령어 살펴보기

  • xargs는 빈칸이나 새 줄로 구분된 표준 입력에서 인수를 읽고 명령의 인수로 입력을 사용하여 지정된 명령을 실행. 명령이 제공되지 않을 경우 기본값은 /bin/echo
$ xargs [OPTIONS] [COMMAND [initial-arguments]]

xargs를 사용하는 가장 기본적인 예는 pipe to xargs 를 사용하여 공백으로 구분된 여러 문자열을 전달하고 해당 문자열을 인수로 사용할 명령을 실행하는 것


touch 커맨드로 파일생성

$ touch file1 file2 file3

xargs 커맨드로 파일생성

$ echo "file1 file2 file3" | xargs touch 

구분기호 지정방법

  • -d(--delimiter) 옵션을 사용하여 단일 문자 또는 \로 시작하는 이스케이프 시퀀스가 될 수 있는 사용자 지정 구분 기호를 설정함
$ echo "test1;test2;test3" | xargs -d \; touch 

실행 전 터미널에 명령 인쇄

  • -t (--verbose) 옵션 : 실행 전 터미널에 명령 인쇄
  • -p (--interactive) 옵션 : 각 명령 실행 전 실행할지 여부를 묻는 메시지 표시
$ echo "test1 test2 test3" | xargs -t touch

여러 명령어 실행

  • -I(대문자i) : 해당 옵션 뒤에 replace-str을 정의하고 replace-str이 모두 xargs에 전달된 인수로 대체됨
# % : replace-str (임의로 지정)
# {} 내 띄어쓰기 유의

$ echo "test1 test2 test3" | xargs -I % sh -c '{ touch %; ls -lh %; }'

-rw-rw-r-- 1 user-01 user-01 0 122 14:29 test1
-rw-rw-r-- 1 user-01 user-01 0 122 14:29 test2
-rw-rw-r-- 1 user-01 user-01 0 122 14:29 test3

xargs + find 명령어 혼합 사용

  • 아래 코드에서 find는 /var/log/ 디렉토리에 있는 모든 파일의 전체 이름을 출력하여 xargs는 rm 명령으로 파일 경로를 전달
  • 새 줄이나 다른 특수 문자를 포함하는 파일 이름에 문제가 발생하지 않도록 하려면 항상 find -print0 옵션을 사용하기
  • 이 옵션을 사용하면 find는 전체 파일 이름과 null 문자를 인쇄함. 이 출력은 -0, (--null) 옵션을 사용하여 xargs로 올바르게 해석할 수 있음
$ find /var/log -type -f -print0 | xargs -0 rm -f

파일 권한 수정

$ find . -type f -name "*.sh" 2>/dev/null | xargs -I / chmod 700 /

$ ls -lh | grep "*.sh"

-rwx------ 1 ncloud ncloud    0 Mar 12 02:19 test.sh

가장 최신파일만 남기고 삭제하기

  • 지정된 디렉토리 내의 파일 중 가장 최신파일만 남기고 모두 삭제

1초 단위로 테스트용 파일 10개 생성 (백그라운드 실행)

$ for i in {1..10}; do sleep 1; touch test_${i}; done &

./test 디렉토리 기준으로 타입이 파일이고, 이름 중 test로 시작하는 모든 파일 검색

$ find ./test -type f -name "test*" -printF '%T@ %p\n' | sort -n | head -n 2

파일 위치 및 파일 명만 나타나게 수정 후 파일 삭제

$ find ./test -name "test*" -type f -printf '%T@ %p\n' | sort -n | head -n 2 | awk '{print $2}' | xargs -I / rm /

특정 확장명만 검색 후, 그 중 가장 최신자료 1개만 삭제

find "경로" -type f -name "*.jpg" -mtime -30 | sort -n | tail -n 1 | xargs -I / rm /


xargs와 파이프의 차이점

예시를 들어 한번 살펴보자

$ echo "test" > test.txt
$ echo test.txt | cat
$ echo err.txt | xargs cat

image


똑같이 전의 명령 결과를 cat의 인자로서 파이프로 던져준건데, 왜 출력 결과가 다를까?

❗️ info


파이프 |는 앞의 결과를 인자로 받는게 아님

파이프 |는 앞의 표준 출력을 다음 프로그램의 표준 입력으로 연결하는 것

파이프 |와의 조합으로 표준 출력을 다음 프로그램의 "인자"로 넘길려면 xargs 커맨드를 사용하면 된다.

xargs 프로그램은 실행할 대상프로그램을 인자로 받고, xargs 프로그램의 표준 입력을 실행 대상프로그램의 인자로 전달하여 실행함


# echo test.txt 명령 결과인 "test.txt" 문자열이 표준입력으로서 파이프로 넘겨져 cat에서 표준입력 즉, 문자열 그대로를 출력
$ echo test.txt | cat  ==  $ cat <<< "test.txt"
# echo test.txt 명령 결과인 "test.txt" 문자열이 cat의 인자로서 xargs에 담겨져 cat [파일명] 명령 실행
$ echo test.txt | xargs cat  ==  $ cat test.txt

이번에는 grep 명령어와 혼합하여 개념을 다져보자.

$ find -name "output.txt" | xargs grep "qa"  ==  $ grep "qa" output.txt

Loading script...