xargs 없이 stdin에서 얻은 파일을 분류하는 방법

xargs 없이 stdin에서 얻은 파일을 분류하는 방법

쉘을 더 잘 배우고 항상 xargs에 의존할 필요가 없도록 하기 위해 다른 방법을 찾으려고 노력해 왔습니다.

find . -name *.tcl | xargs -I{} cat {}

xargs를 사용하면 혼란스러운 느낌이 들며 이를 달성할 수 있는 여러 가지 방법이 있는지 궁금합니다.

편집: 다른 해결책은 다음을 사용하는 것입니다.

find . -name "*.tcl" | cat `cat /dev/stdin`

왜 파일 이름을 먼저 분류한 다음 문자열 대신 파일로 분류해야 하는지 이해가 안 됩니다...

답변1

하위 프로세스에서 find를 사용하고 출력을 cat에 공급할 수도 있습니다. :)

cat $(find . -name "*.tcl")

답변2

조회 시 exec를 사용할 수 있습니다.

find . -name "*.tcl" -exec cat {} \;

-exec그 사이의 모든 것과 후행은 \;실행할 명령입니다. xargs와 마찬가지로 찾기 결과를 {}로 바꿀 수 있습니다. 발견된 각 파일에 대해 cat이 실행됩니다(xargs가 STDIN을 통해 제공된 파일 목록을 반복하는 방식과 비슷함).

어떤 사람들은 파이프를 사용하지 않거나 다른 응용 프로그램을 시작하지 않기 때문에 이것이 더 효율적이라고 생각할 수도 있습니다.

답변3

을 사용하는 경우 bash다음을 수행하세요.

shopt -s globstar # to match files recursively
cat -- **/*.tcl

답변4

단순화를 위해 제안된 깨끗하고 읽기 쉬운 솔루션을 선호합니다.마크 코말린스키. 그러나 Bash에서는 이를 수행하는 방법이 많이 있습니다. 또 다른 흥미로운 접근 방식은 리디렉션을 완전히 피하고 cat리디렉션을 활용하는 것입니다.

find . -name '*.tcl' -exec sh -c 'printf "%s\n" "$(< {})' \;;

실제로 Bash 내장 기능만 사용하여 모든 작업을 수행하려면 다음과 같이 리디렉션을 사용할 수 있습니다.혼돈이 가져온 글로벌 솔루션:

shopt_globstar_temp="$(shopt -p globstar)";
shopt -s globstar;
for filename in **/*.bat; do
    printf "%s" "$(< "${filename}")";
done;
${shopt_globstar_temp};

이것들은 약간 복잡하지만 여기서 나의 목적은 Bash가 할 수 있다는 것을 보여주는 것입니다.파일 설명자와 리디렉션의 몇 가지 강력한 기능. 주어진 문제에 대해 여러 가지 해결책이 있는 경우가 많습니다.


왜 파일 이름을 먼저 분류한 다음 문자열 대신 파일로 분류해야 하는지 이해가 안 됩니다...

의 출력은 cat /dev/fd/stdin이전 예제와 동일하므로 해당 파일 목록으로 효과적으로 대체 find되고 해당 파일 목록을 인수 목록으로 사용합니다.<filename1>.tcl <filename2>.tcl ...cat

같은 예에서 cat을 사용해야 하는 이유가 궁금하다면 모든 프로그램이 인수를 같은 방식으로 처리하는 stdin것은 아니기 때문입니다 . 을 통해 stdin데이터를 전송하면 읽을 파일 이름으로 해석되지 않고 동일한 데이터가 단순히 출력됩니다.catstdincat

관련 정보