디렉토리의 모든 파일에 대해 명령 실행
누군가 다음을 수행할 코드를 제공해 주시겠습니까?프로그램을 통해 모든 파일을 실행해야 하는 파일 디렉토리가 있다고 가정합니다.프로그램은 결과를 표준 출력으로 출력합니다.저는 디렉토리에 들어가 각 파일에서 명령을 실행하고 출력을 하나의 큰 출력 파일로 압축할 스크립트가 필요합니다.
예를 들어, 하나의 파일에서 명령을 실행하려면 다음과 같이 하십시오.
$ cmd [option] [filename] > results.out
다음 bash 코드는 $file을 명령에 전달합니다. 여기서 $file은 /dir의 모든 파일을 나타냅니다.
for file in /dir/*
do
cmd [option] "$file" >> results.out
done
예
el@defiant ~/foo $ touch foo.txt bar.txt baz.txt
el@defiant ~/foo $ for i in *.txt; do echo "hello $i"; done
hello bar.txt
hello baz.txt
hello foo.txt
이거 어때:
find /some/directory -maxdepth 1 -type f -exec cmd option {} \; > results.out
-maxdepth 1
인를사용찾면기하가위디로재귀내로수있다습니방지할것을려가 (할 수 (이러한 중첩된 디렉토리를 처리하려면 이 항목을 생략할 수 있습니다.)-type -f
일반 파일만 처리하도록 지정합니다.-exec cmd option {}
도망치라고 합니다.cmd
된 시된대로option
파일이된 각 파일 이 발된각파대해, 파이이대됨체름에견으로{}
\;
명령의 끝을 나타냅니다.- 인 마으로개, 의인출력은든의 입니다.
cmd
이 " 이다리로션됨렉디"로 .results.out
그러나 파일이 처리되는 순서가 중요한 경우 루프를 작성하는 것이 좋습니다.생각합니다find
파일을 inode 순서로 처리합니다(내가 틀릴 수 있지만). 이것은 사용자가 원하는 것이 아닐 수 있습니다.
명령줄에서 라즈베리 파이를 실행하고 있습니다.
for i in *; do cmd "$i"; done
승인된/높은 투표율의 답변은 훌륭하지만, 몇 가지 핵심적인 세부 사항이 부족합니다.이 게시물에서는 셸 경로 이름 확장(glob)이 실패했을 때, 파일 이름에 새 줄/대시 기호가 포함되어 있고 결과를 파일에 쓸 때 명령 출력 방향을 for-loop 밖으로 이동했을 때 보다 효율적으로 처리하는 방법에 대해 설명합니다.
을 사용하여 *
디렉터리에 파일이 없는 경우 확장이 실패할 가능성이 있으며 실행할 명령에 확장되지 않은 글로벌 문자열이 전달되어 바람직하지 않은 결과를 초래할 수 있습니다.그bash
은 셸이 사용 확셸옵제공다니합을 사용하여 셸 합니다.nullglob
의 파일이 있는 .
shopt -s nullglob
for file in ./*; do
cmdToRun [option] -- "$file"
done
이렇게 하면 식을 사용할 때 for 루프를 안전하게 종료할 수 있습니다../*
파일을 반환하지 않습니다(디렉토리가 비어 있는 경우).
POSIX 호환)nullglob
이라bash
for file in ./*; do
[ -f "$file" ] || continue
cmdToRun [option] -- "$file"
done
이 한 번 했을 때 수 , 이 "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""[ -f "$file" ]
해제된 문자열이 있는지 확인합니다../*
디렉터리에 유효한 파일 이름입니다. 그렇지 않습니다.따라서 이 조건에서 실패할 경우,continue
우리는 다시 시작합니다.for
루프가 계속 실행되지 않습니다.
또한 의 사용법에 유의하십시오.--
파일 이름 인수를 전달하기 직전입니다.앞서 설명한 것처럼 셸 파일 이름에는 파일 이름의 임의 위치에 대시가 포함될 수 있기 때문에 이 작업이 필요합니다.일부 셸 명령은 이름이 제대로 따옴표로 묶이지 않은 경우 이를 명령 옵션으로 해석하고 플래그가 제공된 경우 명령을 실행합니다.
그--
이 경우 명령행 옵션의 끝을 나타냅니다. 즉, 명령어는 이 지점 이후의 문자열을 명령 플래그로 구문 분석하지 않고 파일 이름으로만 구문 분석해야 합니다.
파일 이름을 두 번 따옴표로 묶으면 이름에 글로벌 문자나 공백이 포함된 경우 문제가 해결됩니다.그러나 *nix 파일 이름에는 새 줄이 포함될 수도 있습니다. 우리는 유효한가 될 수 한 문자인 byte(null byte)로 파일 이름을 .\0
) 그 때부터.bash
으로 용내를 사용합니다.C
style 후보입니다. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 이에 적합한 후보입니다.
그래서 사용하는 것은printf
하는 셸 은 NULL을 합니다.-d
.read
명령, 우리는 아래에서 할 수 있습니다.
( shopt -s nullglob; printf '%s\0' ./* ) | while read -rd '' file; do
cmdToRun [option] -- "$file"
done
그nullglob
리고그고.printf
에 감겨 있습니다.(..)
즉, 그것들은 기본적으로 하위 셸(어린이 셸)에서 실행된다는 것을 의미합니다, 왜냐하면 그것들은 피하기 위해서입니다.nullglob
명령이 종료되면 상위 셸에 반영하는 옵션입니다. 그-d ''
.read
명령이 POSIX를 준수하지 않기 때문에bash
이 일을 하기 위한 껍질.용사를 합니다.find
명령 이것은 다음과 같이 수행될 수 있습니다.
while IFS= read -r -d '' file; do
cmdToRun [option] -- "$file"
done < <(find -maxdepth 1 -type f -print0)
위해서find
를 지원하지 않는-print0
및(GNU 및 FreeB) 제외) 수 .printf
find . -maxdepth 1 -type f -exec printf '%s\0' {} \; | xargs -0 cmdToRun [option] --
또 다른 중요한 해결책은 재방향을 for-loop 밖으로 이동하여 많은 수의 파일 I/O를 줄이는 것입니다.루프 내에서 사용할 경우 셸은 for-루프의 각 반복에 대해 열림과 파일과 관련된 파일 설명자를 닫기 위해 시스템 호출을 두 번 실행해야 합니다.이는 대규모 반복 작업을 수행하는 데 있어 성능에 걸림돌이 될 것입니다.루프 외부로 이동하는 것이 좋습니다.
이 수정으로 위의 코드를 확장하면, 당신은 할 수 있습니다.
( shopt -s nullglob; printf '%s\0' ./* ) | while read -rd '' file; do
cmdToRun [option] -- "$file"
done > results.out
기본적으로 파일 입력의 각 반복에 대한 명령 내용을 stdout에 넣고 루프가 끝나면 대상 파일을 한 번 열어 stdout의 내용을 쓰고 저장합니다.find
의 경우에는 한버은동전일동이 될 입니다.
while IFS= read -r -d '' file; do
cmdToRun [option] -- "$file"
done < <(find -maxdepth 1 -type f -print0) > results.out
사용할 수 있습니다.xarg
:
ls | xargs -L 1 -d '\n' your-desired-command
-L 1
한 번에 하나의 항목을 통과시킵니다.-d '\n'
는 출을분다니합의 합니다.ls
새로운 라인을 기준으로 합니다.
작업을 수행하는 빠르고 더러운 한 가지 방법은 다음과 같습니다.
find directory/ | xargs Command
예를 들어, 현재 디렉터리의 모든 파일에서 줄 수를 찾으려면 다음 작업을 수행합니다.
find . | xargs wc -l
@Jim Lewis의 접근 방식을 기반으로 합니다.
다음은 다음을 사용한 빠른 솔루션입니다.find
파일을 수정 날짜별로 정렬합니다.
$ find directory/ -maxdepth 1 -type f -print0 | \
xargs -r0 stat -c "%y %n" | \
sort | cut -d' ' -f4- | \
xargs -d "\n" -I{} cmd -op1 {}
정렬은 다음을 참조하십시오.
http://www.commandlinefu.com/commands/view/5720/find-files-and-list-them-sorted-by-modification-time
모든 .md 파일을 한 디렉터리에서 다른 디렉터리로 복사해야 했기 때문에 이렇게 했습니다.
for i in **/*.md;do mkdir -p ../docs/"$i" && rm -r ../docs/"$i" && cp "$i" "../docs/$i" && echo "$i -> ../docs/$i"; done
이것은 읽기가 꽤 어렵군요. 그러니 그것을 분해해 봅시다.
당신의 파일들과 함께 디렉토리에 첫번째 cd.
for i in **/*.md;
에 각
mkdir -p ../docs/"$i"
파일이 들어 있는 폴더 외부의 문서 폴더에 디렉터리를 만듭니다.그러면 해당 파일과 동일한 이름의 추가 폴더가 생성됩니다.
rm -r ../docs/"$i"
의결생추폴제의 합니다.mkdir -p
cp "$i" "../docs/$i"
echo "$i -> ../docs/$i"
당신이 한 일을 반향하시오.
; done
하게 잘 ㅠㅠㅠㅠㅠㅠㅠ
최대 깊이
Jim Lewis의 답변과 잘 어울린다는 것을 알게 되었습니다. 다음과 같이 덧붙입니다.
$ export DIR=/path/dir && cd $DIR && chmod -R +x *
$ find . -maxdepth 1 -type f -name '*.sh' -exec {} \; > results.out
순서 정렬
정렬 순서대로 실행하려면 다음과 같이 수정합니다.
$ export DIR=/path/dir && cd $DIR && chmod -R +x *
find . -maxdepth 2 -type f -name '*.sh' | sort | bash > results.out
예를 들어, 이것은 다음과 같은 순서로 실행됩니다.
bash: 1: ./assets/main.sh
bash: 2: ./builder/clean.sh
bash: 3: ./builder/concept/compose.sh
bash: 4: ./builder/concept/market.sh
bash: 5: ./builder/concept/services.sh
bash: 6: ./builder/curl.sh
bash: 7: ./builder/identity.sh
bash: 8: ./concept/compose.sh
bash: 9: ./concept/market.sh
bash: 10: ./concept/services.sh
bash: 11: ./product/compose.sh
bash: 12: ./product/market.sh
bash: 13: ./product/services.sh
bash: 14: ./xferlog.sh
무한 깊이
특정 조건에서 무제한 깊이로 실행하려면 다음을 사용할 수 있습니다.
export DIR=/path/dir && cd $DIR && chmod -R +x *
find . -type f -name '*.sh' | sort | bash > results.out
그런 다음 하위 디렉터리의 각 파일 위에 다음과 같이 놓습니다.
#!/bin/bash
[[ "$(dirname `pwd`)" == $DIR ]] && echo "Executing `realpath $0`.." || return
상위 파일의 본문 어딘가:
if <a condition is matched>
then
#execute child files
export DIR=`pwd`
fi
간단한 해결책은 다음과 같습니다.
sh /dir/* > ./result.txt
언급URL : https://stackoverflow.com/questions/10523415/execute-command-on-all-files-in-a-directory
'programing' 카테고리의 다른 글
프로세스가 lxc/Docker 내부에서 실행되는지 확인하는 방법은 무엇입니까? (0) | 2023.05.11 |
---|---|
HTML.ActionLink 메서드 (0) | 2023.05.11 |
지정된 속성을 가진 속성 목록을 가져오는 방법은 무엇입니까? (0) | 2023.05.11 |
xml을 사용하여 문자열 배열 리소스의 문자열 참조 (0) | 2023.05.11 |
VB의 메서드 본문 내에서는 코드 영역을 사용할 수 없습니다.NET? (0) | 2023.05.11 |