ファイルの名前を変更して接尾辞を追加する


13

ファイルがあれば、私は新しいファイル名が古いと同じになるような方法で、現在の作業ディレクトリ内のすべてのファイルの名前を変更するコマンドが必要ですが、元のファイル(例えばの行数に対応する接尾語を含むf10を持っています行の後に名前をf_10)に変更する必要があります。

これが私の(動作しない)試みです:

 linenum=$(wc -l); find * -type f | grep -v sh | rename 's/^/ec/'*

あなたはそれを答えにすることができます!(既存の答えに何か新しいものを追加する場合-しかし、それはそうであるように見えます)
フォルカーシーゲル

回答:


13

どうですか:

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

ありがとうございます!このコマンドラインは作業を完了させるようですが、ドット(。)を(_)に変更するにはどうすればよいですか?また、スクリプトはフォルダー内にあるため、名前も変更され、スクリプトを1回実行できるようになります(スクリプト名が変更されるため...)
Martin Yeboah

@MartinYeboahの更新された回答を参照してください_。スクリプトについては、どのスクリプトですか?これはコマンドラインから実行する必要があり、スクリプトは必要ありません。一部のファイルとのみ一致させたい場合in *は、たとえばに変更しますin *txt
テルドン

ありがとうございました;)コマンドラインから実行する必要があることを完全に忘れました:)
マーティンイェボ

wc -l < $fgrepの代わりに理解する方が簡単だと思います(そして実行する方が良いかもしれませんが、私はそれをチェックしていません)。
マスク

@musiKkはい、しかし、他の答えはを使用wcしているため、別のアプローチを示したかったのです。でも結構です。
テルドン

10

この1つのライナーを試すことができます:

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

6

を使用して拡張機能を保持する別の方法(存在する場合)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
AB

1
これはabcdで失敗しませんか?2番目のキャプチャグループをに変更し(\.?[^\.]+)ます。
ps95

@ prakharsingh95それ(\.?[^\.]+)は事実ですが、2番目のドットまでしか一致せず、連続するドットを持つファイル名やドットで終わるファイル名とは一致しないため、大丈夫ではありません。簡単な解決策ではありません。2つの代替方法があるようです。
コス

@kosあなたは正しいです。([^ \。] +)。*?([^ \。] + $)はどうでしょうか。最適性についてはわかりません。作業フィドル:regex101.com/r/rQ9lX1/1
ps95

1
@ prakharsingh95 .文字クラス内でエスケープしたくない。
テルドン

5

を使用して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 "*"?テストの残り物?;)
コス

1
@kos古い習慣:\
AB

3

ただ楽しみのために、ソリューションをくすくす笑いrenameます。評価されrenameた任意の文字列を受け入れるPerlツールであるため、あらゆる種類のシェナンガンを実行できます。動作すると思われる解決策は次のとおりです。

rename 's/.*/open(my $f, "<", $_);my $c=()=<$f>;$_."_".$c/e' *

興味深いアイデア+1
AB

2

以下のスクリプトは、単一のドットと拡張子(file.txt)、複数のドットと拡張子(file.1.txt)、連続したドット(file..foobar.txt)、およびファイル名のドット(file。またはファイル..)。

スクリプト

#!/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

ファイルには行がないことに注意してください。and file ..、したがって、行カウントは0です

スクリプトと提案された編集をレビューしてくれたterdonとHelioに感謝します。


2

チャット@Helioを使用して開発された別のbash方法:

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、ではなく..)のみに一致する必要があります。拡張子がない場合、BASH_REMATCH配列は空になります。filenameにデフォルト値を${BASH_REMATCH[1]:-$file}使用し、拡張子をそのまま使用することで、これを利用できます。

ドットファイルを処理するfindには、terdonとHelioが示唆するように、を使用できます。

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

+1:コマンドの説明をすることはできません。;-)
Helio
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.