xargs 및 stdin/stdout 리디렉션

xargs 및 stdin/stdout 리디렉션

나는 달리고 싶다 :

./a.out < x.dat > x.ans

각각*.dat디렉토리의 파일.

물론 이것은 bash/python/모든 스크립트를 통해 수행할 수 있지만 저는 섹시한 풍자를 쓰는 것을 좋아합니다. 내가 달성할 수 있는 것은 (아직 stdout 없이) 다음과 같습니다.

ls A/*.dat | xargs -I file -a file ./a.out

하지만-ㅏ교체-str '파일'은 xargs에서 인식되지 않습니다.

도와주셔서 감사합니다.

답변1

첫 번째,ls출력을 파일 목록으로 사용하지 마십시오. 쉘 확장을 사용하거나 find잠재적인 결과는 아래를 참조하십시오.ls+xargs오용과 올바른 사용의 예 xargs.

1. 간단한 방법:~을 위한반지

아래 파일만 처리하려면 A/간단한 for루프로 충분합니다.

for file in A/*.dat; do ./a.out < "$file" > "${file%.dat}.ans"; done

2. 왜   pre1이ls | xargs 아닌가  ?

ls다음은 작업을 수행하기 위해 with를 사용하면 xargs상황이 얼마나 나빠질 수 있는지 에 대한 예입니다 . 다음 시나리오를 고려해보세요.

  • 먼저 빈 파일을 만들어 보겠습니다.

    $ touch A/mypreciousfile.dat\ with\ junk\ at\ the\ end.dat
    $ touch A/mypreciousfile.dat
    $ touch A/mypreciousfile.dat.ans
    
  • 파일을 살펴보면 아무것도 포함되어 있지 않은 것을 알 수 있습니다.

    $ ls -1 A/
    mypreciousfile.dat
    mypreciousfile.dat with junk at the end.dat
    mypreciousfile.dat.ans
    
    $ cat A/*
    
  • 다음을 사용하여 마법 명령을 실행하십시오 xargs.

    $ ls A/*.dat | xargs -I file sh -c "echo TRICKED > file.ans"
    
  • 결과:

    $ cat A/mypreciousfile.dat
    TRICKED with junk at the end.dat.ans
    
    $ cat A/mypreciousfile.dat.ans
    TRICKED
    

그래서 당신은 성공적으로 다루었 mypreciousfile.dat습니다 mypreciousfile.dat.ans. 해당 파일에 내용이 있으면 삭제됩니다.


2. 사용법   xargs : 올바른 사용법  find 

계속 사용하려면 (null로 끝나는 이름)을 xargs사용하세요 .-0

find A/ -name "*.dat" -type f -print0 | xargs -0 -I file sh -c './a.out < "file" > "file.ans"'

두 가지 사항에 유의하세요.

  1. 이렇게 하면 .dat.ans다음으로 끝나는 파일을 만들 수 있습니다.
  2. 이것깨질 것이다파일 이름에 따옴표( ")가 포함된 경우.

두 가지 문제는 서로 다른 셸 호출 방법을 통해 해결될 수 있습니다.

find A/ -name "*.dat" -type f -print0 | xargs -0 -L 1 bash -c './a.out < "$0" > "${0%dat}ans"'

3. 모두 완료find ... -exec

 find A/ -name "*.dat" -type f -exec sh -c './a.out < "{}" > "{}.ans"' \;

.dat.ans파일 이름에 가 포함되어 있으면 파일이 다시 생성됩니다 ". 이렇게 하려면 bash파일 호출 방식을 사용하고 변경하세요.

 find A/ -name "*.dat" -type f -exec bash -c './a.out < "$0" > "${0%dat}ans"' {} \;

답변2

GNU 병렬 처리 사용:

parallel ./a.out "<{} >{.}.ans" ::: A/*.dat

보너스: 처리를 병렬로 수행할 수 있습니다.

자세히 알아보려면 소개 비디오를 시청하세요.http://www.youtube.com/watch?v=OpaiGYxkSuQ

답변3

다음과 같이 시도해 보십시오(구문은 사용하는 셸에 따라 다를 수 있습니다).

$ for i in $(find A/ -name \*.dat); do ./a.out < ${i} > ${i%.dat}.ans; done

답변4

적어도 xargs에서 쉘 호출이 필요하다고 생각합니다.

ls A/*.dat | xargs -I file sh -c "./a.out < file > file.ans"

편집: 파일 이름에 공백이 포함되어 있으면 이 방법이 작동하지 않는다는 점에 유의해야 합니다.일할 수 없습니다. xargs가 공백을 올바르게 이해하도록 find -0 및 xargs -0을 사용하더라도 -c 쉘 호출로 인해 덜거덕거리게 됩니다. 그러나 OP는 xargs 솔루션을 명시적으로 요청했으며 이것이 제가 생각해낸 최고의 xargs 솔루션입니다.파일 이름의 공백이 문제일 수 있는 경우 find -exec 또는 쉘 루프를 사용하십시오.

관련 정보