특정 줄 수의 파일만 나열(또는 이동)하시겠습니까?

특정 줄 수의 파일만 나열(또는 이동)하시겠습니까?

여러 개의 두 줄 구성 파일을 사용하여 작업할 때 줄 수가 다른 모든 파일을 제외할 수 있는 방법을 원합니다.

따라서 다음과 같습니다.

mv * destdir only if file contains exactly two lines

또는:

wc -l * | grep '^ *2' | xargs mv {} destdir

그러나 이 중 어느 것도 실제 작동하는 코드는 아닙니다.

이 글을 쓰면서 나는 깨달았다.하다이를 수행하는 방법이 있는데, 보기 흉하므로 아래 답변에 포함시켰습니다.

이 작업을 수행하는 쉽고 깨끗한 방법이 있습니까?

답변1

너의 서투른 해결책초보자에게는 나쁘지 않습니다. awk행 수를 제공할 뿐만 아니라 이를 표시할 수도 있다는 사실을 놓칠 뿐입니다.출구다음을 사용하여 연결할 수 있도록 올바른 상태 코드를 사용하세요 cp.

for file in * ; do awk 'NR==3{exit}END{exit NR!=2}' "$file" && cp "$file" /tmp; done

NR레코드 수입니다, 그리고 제안한 대로@don_crissti대답은 NR==3세 번째 줄을 만나면 확인을 사용하여 추가 처리를 중지할 수 있다는 것입니다.

NR!=2awkis true/false값 이 흥미로워 보이지만 이것이 제대로 작동하려면 1/0셸에서 0성공 상태를 나타내야 합니다. &&그 반대의 경우도 마찬가지입니다(보았을 때 반응이 얼마나 강한지에 따라 다름 !=).

for file in * ; do awk 'NR==3{exit}END{exit NR==2}' "$file" || cp "$file" /tmp; done

답변2

, 온라인(규칙은 여전히 ​​실행됨)을 사용할 수 있고 awk, 그렇지 않은 경우 블록에서 ,을 사용할 수 있습니다. 행 수는 다음과 같습니다.exit3ENDexit 1END2zsh

print -rl -- *(.e_'awk "NR==3{exit}END{if(NR!=2){exit 1}}" $REPLY'_)

현재 디렉터리에 있는 두 줄의 파일이 나열됩니다. 해당 파일을 이동하려면 대상을 바꾸고 추가하세요 print -rl. 다른 쉘의 경우:mv

for file in ./*; do [[ -f $file ]] && \
awk 'NR==3{exit};END{if(NR!=2){exit 1}}' "$file" && mv "$file" "$dest"
done

z쉘을 사용하는 것과 같은 다른 방법
게누 awk:

awk 'ENDFILE{if(FNR==2){print FILENAME}}' ./*(.)

또는게누 sed(동사 4.2.2또는 그 이후):

sed -ns '2{$F}' ./*(.)

파일 1 과 예제를 두 줄로 나열합니다.

for f (./*(.))
sed -n '2{$Q 1};3q' $f || mv $f $dest

그들을 옮기려고.


1: 전체 입력을 거치므로 대용량 파일을 처리하는 경우에는 적합하지 않습니다. 이 경우 sed -n '2{$F};3q'각 파일을 대상으로 지정하거나 첫 번째 awk 솔루션을 사용해야 할 수 있습니다.

답변3

파일 이름이 상당히 평범하고 :줄바꿈과 줄 바꿈으로 구분할 수 있는 경우 다음을 수행하세요.

grep -m3 '' ./* ./*/* |
cut -d: -f1 | uniq -c |
grep -v '^ *[13] ' 

^이 명령은 현재 디렉터리와 두 줄만 포함하는 모든 직계 하위 디렉터리에 있는 점이 아닌 모든 파일을 나열합니다.

uniqglob이 이미 정렬되어 있으므로 실제로 정렬에 대해 걱정할 필요가 없습니다 . 세 번째 입력 줄에서 종료하는 것이 -m끝까지 계속하는 것보다 훨씬 빠르기 때문에 GNU axe 일치 옵션을 사용 하지만 이 옵션 없이도 작동합니다. grep아이디어는 grep포함된 각 줄의 파일 이름을 인쇄한 다음 출력에서 ​​각 파일 이름이 나타나는 횟수를 계산한 다음 2보다 크거나 작은 것을 필터링하는 것입니다.

나는 임의의 소스 코드 디렉터리에 대해 이것을 실행했고, 그들 모두에는 단 두 줄만 포함하는 두 개의 파일이 있었습니다.

  2 ./dex/coll.sh
  2 ./jimtcl/jim-config.h.in

마지막 줄을 다음으로 바꾸는 것이 더 깔끔할 것입니다.

... |
sed -ne's/^ *2  *//p'

...하지만.

답변4

사용할 -t대상 디렉터리 mv옵션 xargs:

wc -l * | sed -n 's/^[[:space:]]*2[[:space:]]\+//p'  | xargs mv -t "$DESTDIR"

관련 정보