ファイル名を見つけてアルファベット順に並べ替え、最初の3文字だけを表示するにはどうすればよいですか?

ファイル名を見つけてアルファベット順に並べ替え、最初の3文字だけを表示するにはどうすればよいですか?

現在のディレクトリですべてのファイルを見つけて内容を処理する前に、アルファベット順にソートして各ファイルの最初の3文字を抽出したいと思います。これにより、他のファイルにリダイレクトできる文が生成されます。私はこれを試しました:

find . -type f -exec basename {} \; | sort | xargs head -c 3

しかし、私は次のようになります。

ヘッド:読み取り用に 'filenamehere'を開くことができません。そのファイルやディレクトリはありません。

すべてのファイルに対して最初の3文字を抽出しようとしています。まず、ソートせずにこれを実行できました。

答え1

編集する: 初めて:

find -type f -exec grep -I -q . {} \; -exec sh -c 'echo -e "$(basename "$0") {}"' {} \; | sort | cut -d ' ' -f2 |  xargs sed -Ee 's/(^.{3})(.*)/\1/g'

grep -I -q . {} \;画像などのバイナリファイルは検索されず、すべてのテキストファイルのみが検索されます。

第二:

私の基本的なアイデアは、キーが基本名と同じで、値が最初の3文字であるハッシュ関数を作成することです。

#!/bin/bash
touch file_s
echo 'declare -A map' > file_s
find . ! -name file_s ! -name sort_map -type f -exec grep -I -q . {} \; \
-exec sh -c 'i="$(basename "$0")";echo "map["$i"]=$(head -n 1 "$0"|cut -c 
1-3)" >> file_s;' {} \; | sort | while read -r line
do
source file_s
echo -e ${map["$line"]}
done

このコードを書く必要があるスクリプトの名前は一時的sort_mapですfile_s。文書。したがって、findコマンドにこれら2つのファイルを含めないでください。grep -I -q . {} \;grepファイルをバイナリファイルではなくテキストファイルとしてのみ作成します。

2番目の-execコマンドは次のとおりです。

i="$(basename "$0")";デフォルト名を取得し、変数iに書き込みます。

echo "map["$i"]=$(head -n 1 "$0"|cut -c 1-3)" >> file_s;ハッシュ関数とその値を一時ファイルに書き込みますfile_s

sortファイル名がソートされます。

while read -r line
do
source file_s
echo -e ${map["$line"]}
done

ファイルを1行ずつ読み込み、インポートしますfile_s。これで最初の3文字が印刷されます。


head はファイル名ではなくファイルの内容を印刷するため、head は使用できません。

あなたはそれを使用することができます:

find . -type f -exec basename {} \; | sort  | cut -c 1-3

bまたは、オプションを代わりに使用できますが、cすべての文字が1バイトであると仮定します。

find . -type f -exec basename {} \; | sort  | cut -b 1-3

最初の3文字を取得します。

あなたはそれを使用することができます:

find . -type f -exec basename {} \; | sort | sed -Ee 's/(^.{3})(.*)/\1/g'

ファイルを並べ替え、最初の3文字を一致させてのみ印刷します。

メモ:これらのコマンドはすべて、スペースとタブを1文字として扱います。

答え2

basenameNETのすべてのファイルに対して実行しないでくださいfind。見つかったすべてのファイルに対してシェルを実行するのは膨大なリソースの無駄です。

find(GNUバージョンを想定すると、他のバージョンでもサポートできます。)ファイル名だけでなく、サイズ、所有権、権限などを含むファイルに関する情報を出力する方法を示すフォーマット文字列を使用するfindディレクティブがあります。-printf

1つの形式は、使用している形式%fであるファイル名からすべての先行ディレクトリを削除することです。basenameだからあなたは使用することができます

find -type f -printf '%f\n'

\n各ファイル名が1行に表示されるように改行を追加する必要があります。

もう1つの利点は、この方法で印刷する文字数に制限を追加できることです。最大3文字のファイル名を印刷するには、次のようにします。

find -type f -printf '%.3f\n'

sortミックスに追加します。

find -type f -printf '%.3f\n' | sort

あなたはあなたの解決策を持っています。

編集:ファイルをソートしてからその内容の最初の3文字を出力する必要があるように見えるので、コマンドは次のようになります。

find -type f -printf '%f\t%p\n' | sort | cut -f2  | xargs head -n 1 | cut -c1-3

これはフォーマット文字列を使用して最初にデフォルトのファイル名のみを表示し、次にタブ、最後にフルパスを表示します。ファイル名を簡単にソートするために使用できます。

cut -f2タブの後ろ部分のみを抽出します。

xargs head -n 1各ファイルの最初の行を取得します。

cut -c1-3各行の最初の3文字を表示します。

このhead -n 1部分はパイプラインに必要です。それ以外の場合は、cut各ファイルの各行の最初の3文字が表示されます。

答え3

GNUヘッド(用-q)とシェルのデフォルトのワイルドカード拡張ソートを使用してください。

head -q -c 3 * > /tmp/output

または、

for file in *; do dd status=none if="$file" bs=1 count=3; done > /tmp/output

ファイルが単一のサブディレクトリにある場合(基準:あなたの別のコメント)次にワイルドカードを調整します。

head -q -c 3 /directory/subdirectory/* > /tmp/output

そして

for file in /directory/subdirectory/* # ...

答え4

だから私はついに答えからインスピレーションを得た独自のソリューションでこの問題を解決しました。 1つではなく3つのコマンドで実行する必要がありました。私はこれをしました:

mkdir holder
find . -type f -exec mv -t holder {} \;
head -qc 3 ./holder/* > prophetie.txt

これにより、文全体が必要に応じて左から右に流れます。私は

ls -l holder

それらはすべてアルファベット順になっています。これを行うときに並べ替える必要さえありません。 mvコマンドがソートしていると思いますか?

関連情報