예를 들어, 지금은 유닉스 경로를 파일에 쓴 두 개의 파일을 변경하기 위해 다음을 사용하고 있습니다.
cat file.txt | while read in; do chmod 755 "$in"; done
더 우아하고 안전한 방법이 있습니까?
답변
파일을 한 줄씩 읽고 명령을 실행하십시오.
답변이 하나뿐이 아니기 때문에 …
shell
명령 줄 확장xargs
전용 도구while read
약간의 언급과 함께while read -u
대화식 처리를fd
위해 전용 사용 (샘플)
영업 요청에 대해서 : 실행 chmod
파일에 나열된 모든 대상에하는 것은 , xargs
지정된 도구입니다. 그러나 다른 응용 프로그램, 소량의 파일 등의 경우 …
-
전체 파일을 명령 줄 인수로 읽습니다.
파일이 너무 크지 않고 모든 파일 이름 이 공백이나 따옴표와 같은 다른 특수 문자없이 잘 지정되어 있으면
shell
명령 줄 확장을 사용할 수 있습니다 . 간단히:chmod 755 $(<file.txt)
적은 양의 파일 (줄)의 경우이 명령이 더 밝습니다.
-
xargs
올바른 도구입니다더 많은 양의 파일 또는 입력 파일의 거의 모든 행 수
많은 바이너리 유틸리티의 도구, 등
chown
,chmod
,rm
,cp -t
…xargs chmod 755 <file.txt
당신은 특수 문자 및 / 또는 라인의 많은 경우
file.txt
.xargs -0 chmod 755 < <(tr \\n \\0 <file.txt)
항목별로 명령을 정확히 1 회 실행해야하는 경우 :
xargs -0 -n 1 chmod 755 < <(tr \\n \\0 <file.txt)
chmod
여러 파일을 인수 로 허용하므로이 샘플에서는 필요하지 않지만 질문 제목과 일치합니다.특별한 경우에는 다음에 의해 생성 된 명령에서 파일 인수의 위치를 정의 할 수도 있습니다
xargs
.xargs -0 -I '{}' -n 1 myWrapper -arg1 -file='{}' wrapCmd < <(tr \\n \\0 <file.txt)
seq 1 5
입력으로 테스트이 시도:
xargs -n 1 -I{} echo Blah {} blabla {}.. < <(seq 1 5) Blah 1 blabla 1.. Blah 2 blabla 2.. Blah 3 blabla 3.. Blah 4 blabla 4.. Blah 5 blabla 5..
여기서 commande는 한 줄에 한 번 수행됩니다 .
-
while read
및 변형.OP가 제안한
cat file.txt | while read in; do chmod 755 "$in"; done
대로 작동하지만 두 가지 문제가 있습니다.-
cat |
입니다 쓸모 포크 ,와 -
| while ... ;done
이후 환경이 붕괴 되는 서브 쉘 이 될 것;done
입니다.
그래서 이것은 더 잘 쓰여질 수 있습니다 :
while read in; do chmod 755 "$in"; done < file.txt
그러나,
-
경고
$IFS
및read
플래그 가 표시 될 수 있습니다 .help read
read: read [-r] ... [-d delim] ... [name ...] ... Reads a single line from the standard input... The line is split into fields as with word splitting, and the first word is assigned to the first NAME, the second word to the second NAME, and so on... Only the characters found in $IFS are recognized as word delimiters. ... Options: ... -d delim continue until the first character of DELIM is read, rather than newline ... -r do not allow backslashes to escape any characters ... Exit Status: The return code is zero, unless end-of-file is encountered...
경우에 따라 사용해야 할 수도 있습니다
while IFS= read -r in;do chmod 755 "$in";done <file.txt
이상한 파일 이름 문제를 피하기 위해. 그리고 아마도 다음과
UTF-8
같은 문제를 유발한다면 :while LANG=C IFS= read -r in ; do chmod 755 "$in";done <file.txt
-
을 (
STDIN
를) 읽는 데 사용하는 동안file.txt
스크립트를 대화식으로 사용할 수 없습니다 (STDIN
더 이상 사용할 수 없음 ).
-
-
while read -u
전용을 사용fd
합니다.구문 :
while read ...;done <file.txt
로 리디렉션STDIN
됩니다file.txt
. 즉, 프로세스가 완료 될 때까지 프로세스를 처리 할 수 없습니다.대화식 도구 를 작성하려는 경우
STDIN
대체 파일 디스크립터 사용 을 피하고 사용해야 합니다 .상수 파일 설명은 다음과 같습니다
0
에 대한 STDIN ,1
대한 STDOUT 및2
대한 STDERR . 당신은 그들을 통해 볼 수 있습니다 :ls -l /dev/fd/
또는
ls -l /proc/self/fd/
거기에서 파일 설명 자로로 (
0
그리고63
실제로는sysctl
수퍼 유저 도구 에 따라) 사용되지 않는 숫자를 선택해야합니다 .이 데모에서는 fd 를 사용합니다
7
.exec 7<file.txt # Without spaces between `7` and `<`! ls -l /dev/fd/
그런 다음
read -u 7
이 방법을 사용할 수 있습니다 .while read -u 7 filename;do ans=;while [ -z "$ans" ];do read -p "Process file '$filename' (y/n)? " -sn1 foo [ "$foo" ]&& [ -z "${foo/[yn]}" ]&& ans=$foo || echo '??' done if [ "$ans" = "y" ] ;then echo Yes echo "Processing '$filename'." else echo No fi done 7<file.txt
done
닫으려면
fd/7
:exec 7<&- # This will close file descriptor 7. ls -l /dev/fd/
참고 : 병렬 프로세스로 많은 I / O를 수행 할 때이 구문이 유용 할 수 있기 때문에
파업버전을보냈습니다.mkfifo sshfifo exec 7> >(ssh -t user@host sh >sshfifo) exec 6<sshfifo
답변
예.
while read in; do chmod 755 "$in"; done < file.txt
이렇게하면 cat
프로세스를 피할 수 있습니다 .
cat
이 같은 목적으로 거의 항상 나쁘다. 쓸모없는 고양이 사용에 대해 더 읽어 볼 수 있습니다 .
답변
좋은 선택 기가있는 경우 (예 : 디렉토리의 모든 .txt 파일) 다음을 수행 할 수 있습니다.
for i in *.txt; do chmod 755 "$i"; done
또는 귀하의 변형 :
while read line; do chmod 755 "$line"; done <file.txt
답변
입력에 공백이 없다는 것을 알고 있다면 :
xargs chmod 755 < file.txt
경로에 공백이있을 수 있고 GNU xargs가있는 경우 :
tr '\n' '\0' < file.txt | xargs -0 chmod 755
답변
각 줄에 대해 명령을 병렬로 실행하려면 GNU Parallel을 사용할 수 있습니다
parallel -a <your file> <program>
파일의 각 줄은 인수로 프로그램에 전달됩니다. 기본적으로 parallel
CPU 수만큼 스레드를 실행합니다. 그러나 당신은 그것을 지정할 수 있습니다-j
답변
bash에 태그를 붙인 것을 보았지만 Perl도 좋은 방법입니다.
perl -p -e '`chmod 755 $_`' file.txt
정규식을 적용하여 올바른 파일을 얻도록 할 수 있습니다 (예 : .txt 파일 만 처리).
perl -p -e 'if(/\.txt$/) `chmod 755 $_`' file.txt
무슨 일이 일어나고 있는지 “미리보기”하기 위해서는 백틱을 큰 따옴표로 바꾸고 앞에 붙입니다 print
.
perl -p -e 'if(/\.txt$/) print "chmod 755 $_"' file.txt
답변
파일을보다 유연하게 처리 할 수있는 AWK를 사용할 수도 있습니다.
awk '{ print "chmod 755 "$0"" | "/bin/sh"}' file.txt
파일에 다음과 같은 필드 구분 기호가있는 경우
field1, field2, field3
첫 번째 필드 만 얻으려면
awk -F, '{ print "chmod 755 "$1"" | "/bin/sh"}' file.txt
GNU 설명서 https://www.gnu.org/software/gawk/manual/html_node/Very-Simple.html#Very-Simple 에 대한 자세한 내용을 확인할 수 있습니다