새 작업 파일 이름이 이전 파일 이름과 같지만 원본 파일의 줄 수에 해당하는 접미사를 포함하여 현재 작업 디렉토리의 모든 파일 이름을 바꾸는 명령이 필요합니다 (예 : 파일 f
에 10이있는 경우) 그런 다음 이름을 f_10
)으로 바꿔야합니다 .
다음은 작동하지 않는 시도입니다.
linenum=$(wc -l); find * -type f | grep -v sh | rename 's/^/ec/'*
새 작업 파일 이름이 이전 파일 이름과 같지만 원본 파일의 줄 수에 해당하는 접미사를 포함하여 현재 작업 디렉토리의 모든 파일 이름을 바꾸는 명령이 필요합니다 (예 : 파일 f
에 10이있는 경우) 그런 다음 이름을 f_10
)으로 바꿔야합니다 .
다음은 작동하지 않는 시도입니다.
linenum=$(wc -l); find * -type f | grep -v sh | rename 's/^/ec/'*
답변:
어때요?
for f in *; do mv "$f" "$f"_$(wc -l < "$f"); done
예를 들면 다음과 같습니다.
$ wc -l *
10 file1
40 file2
100 file3
$ ls
file1_10 file2_40 file3_100
확장을 유지하려면 (있는 경우)이를 대신 사용하십시오.
for f in *; do
ext="";
[[ $f =~ \. ]] && ext="."${f#*.};
mv "$f" "${f%%.*}"_$(wc -l < "$f")$ext;
done
_
. 스크립트는 어떤 스크립트입니까? 그것은 명령 줄에서 실행되어야하며 스크립트가 필요하지 않습니다. 일부 파일 만 일치 시키 in *
려면 예를 들어 in *txt
또는로 변경하십시오 .
wc -l < $f
grep 대신 이해하기가 더 쉬울 것이라고 생각 합니다 (아마도 수행하는 것이 좋지만 확인하지 않았습니다).
wc
하고 있기 때문에 다른 접근법을 보여주고 싶었습니다. 하지만 괜찮아요.
이 하나의 라이너를 사용해보십시오.
find . -maxdepth 1 -type f -exec bash -c 'mv -i "$1" "$1.$(wc -l <"$1")"' _ {} \;
현재 작업 디렉토리에있는 모든 파일을 찾을 수 있습니다 ( find . -maxdepth 1 -type f
).
그런 다음 찾은 파일에 대해 쉘 인스턴스를 실행하여 줄 수를 추가하기 위해 파일 이름을 바꿉니다.
예 :
$ ls
bar.txt spam.txt foo.txt
$ find . -maxdepth 1 -type f -exec bash -c 'mv -i "$1" "$1.$(wc -l <"$1")"' _ {} \;
$ ls
bar.txt.12 foo.txt.24 spam.txt.7
다음을 사용하여 확장 (존재하는 경우)을 유지하는 다른 방법 rename
:
for f in *; do rename -n "s/([^.]+)(\.?.*)/\$1_$(< "$f" wc -l)\$2/" "$f"; done
결과가 예상 한 경우 -n
옵션을 제거하십시오 .
for f in *; do rename "s/([^.]+)(\.?.*)/\$1_$(< "$f" wc -l)\$2/" "$f"; done
rename
위대한 =) +1
(\.?[^\.]+)
.
(\.?[^\.]+)
두 번째 점까지만 일치하고 연속적인 점이있는 파일 이름과 일치하거나 점에 관계없이 끝나는 파일 이름과 일치하지 않기 때문에 문제가되지 않습니다. 쉬운 해결책은 아니지만 유일한 방법은 두 가지 대체를하는 것 같습니다.
.
문자 클래스 안에서 .
사용 find
:
find . -maxdepth 1 -type f -print0 | while read -d $'\0' f; do mv "$f" "$f"_$(grep -c . "$f"); done
예
% wc -l *
3 doit
5 foo
% find . -maxdepth 1 -type f -print0 | while read -d $'\0' f; do mv "$f" "$f"_$(grep -c . "$f"); done
% wc -l *
3 doit_3
5 foo_5
-name "*"
? 시험에서 남은? ;)
스크립트는 단일 점 및 확장명 (file.txt), 다중 점 및 확장명 (file.1.txt), 연속 점 (file..foobar.txt) 및 파일 이름의 점 (파일 또는 파일..).
스크립트
#!/bin/bash
# Author: Serg Kolo
# Date: June 25,2015
# Description: script to rename files to file_numlines
# written for http://askubuntu.com/q/640430/295286
# Where are the files ?
WORKINGDIR=/home/xieerqi/substitutions
# Where do you want them to go ?
OUTPUTDIR=/home/xieerqi/substitutions/output
for file in $WORKINGDIR/* ;do
FLAG=0
EXT=$(printf "%s" "$file" | awk -F'.' '{printf "%s",$NF }' ) # extension, last field of dot-separated string
# EXT="${file##*.}" # Helio's advice is to use parameter expansion, but I dont know how to use it
if [ -z $EXT ]; then # we have a dot at the end case file. or something
# so we gotta change extension and filename
EXT=""
FILENAME=$(printf "%s" "$file" | awk -F '/' '{ print $NF}' )
# set flag for deciding how to rename
FLAG=1
else
FILENAME=$( printf "%s" "$file" | awk -F '/' -v var=$EXT '{gsub("."var,"");print $NF}' ) # filename, without path, lst in
fi
NUMLINES=$(wc -l "$file" | awk '{print $1}') # line count
if [ $FLAG -eq 0 ];then
echo "$file" renamed as "$OUTPUTDIR"/"$FILENAME"_"$NUMLINES"."$EXT"
# cp "$file" "$OUTPUTDIR"/"$FILENAME"_"$NUMLINES"."$EXT" # uncomment when necessary
else
echo "$file" renamed as "$OUTPUTDIR"/"$FILENAME"_"$NUMLINES""$EXT"
# cp "$file" "$OUTPUTDIR"/"$FILENAME"_"$NUMLINES""$EXT" # uncomment when necessary
fi
#printf "\n"
done
실제 스크립트
$./renamer.sh
/home/xieerqi/substitutions/file. renamed as /home/xieerqi/substitutions/output/file._0
/home/xieerqi/substitutions/file.. renamed as /home/xieerqi/substitutions/output/file.._0
/home/xieerqi/substitutions/file.1.jpg renamed as /home/xieerqi/substitutions/output/file.1_3.jpg
/home/xieerqi/substitutions/file.1.test.jpg renamed as /home/xieerqi/substitutions/output/file.1.test_3.jpg
/home/xieerqi/substitutions/file.1.test.txt renamed as /home/xieerqi/substitutions/output/file.1.test_2.txt
/home/xieerqi/substitutions/file.1.txt renamed as /home/xieerqi/substitutions/output/file.1_2.txt
/home/xieerqi/substitutions/file.2.jpg renamed as /home/xieerqi/substitutions/output/file.2_3.jpg
/home/xieerqi/substitutions/file.2.test.jpg renamed as /home/xieerqi/substitutions/output/file.2.test_3.jpg
/home/xieerqi/substitutions/file.2.test.txt renamed as /home/xieerqi/substitutions/output/file.2.test_2.txt
/home/xieerqi/substitutions/file.2.txt renamed as /home/xieerqi/substitutions/output/file.2_2.txt
/home/xieerqi/substitutions/foo..bar.txt renamed as /home/xieerqi/substitutions/output/foo..bar_4.txt
파일에는 줄이 없습니다. 그리고 file .. 따라서 행 수는 0입니다.
스크립트 및 제안 된 수정 사항을 검토 한 terdon과 Helio에게 특별한 감사
채팅에서 @Helio로 개발 한 또 다른 배쉬 방법 :
for file in *
do
echo "$file"
[[ -f "$file" ]] || continue
[[ $file =~ (.*)(\.[^.]+)$ ]]
cp "$file" "output/${BASH_REMATCH[1]:-$file}_$(wc -l < "$file")${BASH_REMATCH[2]}"
done
기절 한 두 번째 머리 ( (.*)(\.[^.]+)$
)가 있는 이상하게 보이는 단정 한 사람은 적절한 확장 ( .foo
, not ..
) 과만 일치해야합니다 . 확장명이 없으면 BASH_REMATCH
배열이 비어 있습니다. filename의 기본값을 ${BASH_REMATCH[1]:-$file}
사용하고 확장명을 그대로 사용하면 이를 활용할 수 있습니다 .
terdon과 Helio가find
제안한대로 도트 파일을 처리하기 위해을 사용할 수 있습니다 .
find -maxdepth 1 -type f -printf '%P\0' |
while IFS= read -r -d '' file
do
[[ $file =~ (.*)(\.[^.]+)$ ]]
cp "$file" "output/${BASH_REMATCH[1]:-$file}_$(wc -l < "$file")${BASH_REMATCH[2]}"
done