긴 파일 이름 목록(전체 경로 포함)이 포함된 파일이 있습니다. 또한 이 목록의 프로그램과 파일 이름을 인수로 사용하여 여러 번 실행하려는 프로그램이 있습니다. 불행하게도 내가 실행하고 싶은 프로그램은 홈브류 스크립트이므로 유일한 옵션은 다음과 같습니다.하나파일 이름을 입력하면 허용되지 않습니다.표준 입력(파일 이름 목록과 같은) - 따라서 파이핑이나 입력 리디렉션이 불가능합니다.
나에게 필요한 것은 실행될 명령입니다다른명령(내 스크립트), 파일의 행을 매개변수로 사용합니다.
find
-action -exec
...( find . -name "*.txt" -exec command \;
) 과 유사합니다 . 내 생각엔 내가 실제로할 수 있다여기에 사용되었지만 find
입력 파일을 정렬하고 싶습니다...
그래서 나에게 필요한 것은 이것이다:
for_each_command1 -f 파일 목록 -c './my_command {}' for_each_command2 -f 파일 목록-exec ./my_command {} \; for_each_command3 -c './my_command {}'이런 종류의 작업을 처리하는 일반적인 방법은
$ wc -l 파일 목록 232화 $ for (( i=1;그렇습니다 > ./my_command "`sed -n "${i}p" 파일 목록`" > 완료sed
- 불행하게도 오버헤드가 많고 별로 좋지 않습니다(하지만하다일하다...):
그렇다면 이러한 일을 처리할 수 있는 내장 명령이나 셸이 있습니까?
답변1
편리하고 xargs -I
귀하의 요구 사항을 완벽하게 충족합니다.
$ xargs <my_file_list.txt -I filename ./my_command "filename"
-I replace-str Replace occurrences of replace-str in the initial-arguments with names read from standard input. Also, unquoted blanks do not terminate input items; instead the separator is the newline character. Implies -x and -L 1.
즉, 줄 바꿈으로 구분된 입력 줄만 취하고 이를 단일 인수로 사용하여 명령을 호출합니다. 개행 문자를 제외한 어떤 것도 구분 기호로 간주되지 않으므로 공백 및 기타 특수 문자는 괜찮습니다.
파일 이름에 개행 문자를 허용하려면 와일드카드의 답변에 따라 Null 종결자도 파일에서 작동합니다.
답변2
귀하의 파일 목록이 "filelist.txt"라는 파일에 저장되어 있고 각 파일 이름이 한 줄에 저장되어 있다고 가정합니다. 그런 다음 각 줄을 다음과 같은 매개변수로 사용하여 스크립트를 호출할 수 있습니다.
while read name; do
./yoursrcipt.sh "$name"
done <filelist.txt
답변3
나는 보통 휴대용(POSIX) 솔루션을 선호하지만,간단하고 명백하다이에 대한 대답은 GNU 확장을 사용하여 삶을 더 쉽게 만드는 것입니다.
find . -type f -name '*.txt' -print0 | sort -z | xargs -n1 -r0 ./mycommand
이는 파일 이름 사이의 구분 기호로 널 바이트를 사용합니다. 이는 파일 이름에 다음이 포함될 수 있기 때문에 중요합니다.어느줄 바꿈을 포함한 문자.
(슬래시는 경로 구성 요소 구분 기호이므로 보존되지만 이 경우에는 파일 구분 기호로 사용할 수 없기 때문에 중요하지 않습니다.)
답변4
$ cat baard.in
/path/to/some space file
/some tabbed/some tabbed file
/path to/genericfile
/path/to/regular.file
/path/to/exciting!/file!
/path/to/(parenthetical)/file.txt
$ cat my_command
#!/bin/sh
printf "my_command: %s\n" "$1"
awk는 이미 행을 구문 분석했으므로 이를 사용하여 각 레코드에 대한 명령을 호출할 수 있으며 인수를 인용할 때 주의해야 합니다.
$ awk '{system("./my_command '\''" $0 "'\''");}' < baard.in
my_command: /path/to/some space file
my_command: /some tabbed/some tabbed file
my_command: /path to/genericfile
my_command: /path/to/regular.file
my_command: /path/to/exciting!/file!
my_command: /path/to/(parenthetical)/file.txt
그러나 입력에 작은따옴표가 있으면 awk 명령이 실패합니다. 예를 들면 다음과 같습니다.
/books/Hitchhiker's Guide to the Galaxy.epub
bash를 사용할 수 있는 경우 다음을 사용할 수 있습니다.
$ readarray -t paths < baard.in
$ for((i=0;i < ${#paths[*]}; i++)); do ./my_command "${paths[i]}"; done
my_command: /path/to/some space file
my_command: /some tabbed/some tabbed file
my_command: /path to/genericfile
my_command: /path/to/regular.file
my_command: /path/to/exciting!/file!
my_command: /path/to/(parenthetical)/file.txt
my_command: /books/Hitchhiker's Guide to the Galaxy.epub
또는 ksh93에서(자일스의 대답은 여기에 있습니다readarray를 수동으로 구현하는 경우):
$ IFS=$'\n'; set -f
$ paths=( $(< baard.in) )
$ unset IFS; set +f
$ for((i=0;i < ${#paths[*]}; i++)) do ./my_command "${paths[i]}"; done
my_command: /path/to/some space file
my_command: /some tabbed/some tabbed file
my_command: /path to/genericfile
my_command: /path/to/regular.file
my_command: /path/to/exciting!/file!
my_command: /path/to/(parenthetical)/file.txt
my_command: /books/Hitchhiker's Guide to the Galaxy.epub