xargs 및 라인별 파이프

xargs 및 라인별 파이프

a.txt, b.txt및 3개의 파일이 있습니다 . , 간단한 텍스트를 포함하는 3 c.txt개의 파일을 만들고 싶습니다 .a.testb.testc.testabracadabra

기본적으로 요점은 .test각 파일에 대한 파일을 만들고 .txt텍스트로 채우는 것입니다. xargs그걸로 이걸 하려고 합니다 .

anlx2626> ls
a.txt  b.txt  c.txt

anlx2626> ls *.txt | awk -F'.txt' '{print $1}' | xargs -I {} echo "abracadabra" > {}.test

anlx2626> ls *.test
ls: No match.

{}라인별 배관에 자리 표시자를 사용하는 것이 예상대로 작동하지 않는 이유를 지적할 수 있는 사람이 있습니까 ?

답변1

이 코드에서는:

xargs -I {} echo "abracadabra" > {}.test

xargs는 리디렉션 연산자를 전혀 볼 수 없습니다 >. 이는 쉘에 의해 해석되어 .xargs라는 파일을 생성합니다 {}.test.

xargs를 사용하여 요청한 작업을 수행하는 한 가지 방법은 sh가 리디렉션 연산자를 해석하도록 하는 것입니다.

xargs sh -c 'for i do echo abracadrabra > "$i"; done' sh

그러나 xargs를 전혀 사용하지 않는 것이 더 나을 것입니다. 다른 답변에서는 방법을 설명합니다.

답변2

awk텍스트를 출력할 수 있으며, 아니요 echo또는 필수입니다 xargs. 귀하의 접근 방식에는 foo-1.2.txt.

개행 문자를 포함하거나 이름이 .txt.

이번에는 여기서 루프를 사용하겠습니다(예: zsh 사용).

(set -o noclobber; for f (*.txt(N)) echo abracadabra > $f:r.test)

또는 POSIX적으로:

(set -o noclobber
 for f in *.txt; do
   echo abracadabra > "${f%.*}.test"
 done)

이는 noclobber기존 파일을 덮어쓰는 것을 방지하기 위한 것입니다. 숨겨진 파일은 무시됩니다. txtPOSIX sh 변형은 파일 이 없으면 파일을 생성합니다 *.test.

답변3

이 질문에 대한 답변은 이미 모두 완료되었지만 다른 방법을 보여주기 위해 다음과 같이 추가했습니다.

while IFS= read -r
do
echo abracadabra > "${REPLY}.test"
done < <(find . -maxdepth 1 -name "*.txt" -exec basename -s .txt {} \;)

여기서 find는 텍스트 파일을 나열하는 데 사용됩니다. maxdepthfind가 하위 폴더로 반복되는 것을 방지하는 데 사용됩니다. basename -s .txt목록 이름을 제외하고는 전혀 필요하지 않기 때문에 txt 확장자를 처음부터 제거하는 데 사용됩니다. while 루프에서는 확장자 없이 이름을 사용하고 문자열 대체를 사용하여 .test파일에 에코하는 동안 확장자를 추가합니다. 우리는 기본 변수인 을 사용 했습니다 while.$REPLY

답변4

for l in $(ls *.txt); do echo "abrakadabra" > $l; done

관련 정보