4

編集:これは正常に回答されたと思いますが、後で確認することはできません. ただし、提案どおりに再フォーマットしました。

質問: それぞれ XXXXNAME という形式の名前を持つ一連のファイルがあります。ここで、XXXX は何らかの数字です。それらをすべて XXXX という別のフォルダーに移動し、NAME という名前にします。これは手動で行うことができますが、それらに XXXXNAME という名前を付けることで、ターミナルにそれらを移動するように指示できる方法があることを望んでいました (正しい名前だと思いますが、よくわかりません)。何かのようなもの

mv *名前 */名前

しかし、最初のケースで * が何であれ、それをパスに逆流させます。

これは、bash シェルを備えた何らかの形式の Linux 上にあります。

実際のケースでは、ファイルは 0000GNUmakefile で、連番が付けられています。研究の一環として、クラスター上でコンパイルして実行するために、類似しているがわずかに変更されたバージョンのプログラムを多数作成する必要があります。最初からすべてのファイルを編集して適切な場所に配置するプログラムを作成する方がおそらくは速かったでしょうが、私はそうしませんでした。

これはおそらく非常に単純で、適切な言葉を知っていれば、自分で答えを見つけることができるはずです. つまり、私はプログラミングの正式なトレーニングを受けていないので、それらを検索するために何と呼ぶべきかわかりません。うまくいけば、これで答えが得られ、次回は自分で同様のことの答えを見つける方法を知ることができます. 私が習得した基本的なプログラミングを使用して、これを行うプログラムを作成できると確信していますが、ターミナルに既にある機能を使用するだけでそれを行う簡単な方法があることを願っています。私はおそらく、これらのもので遊ぶことを許されるべきではありません.

助けてくれてありがとう!私は実際に C と Python でかなりの量のプログラミングを行うことができますが、それは主に試行錯誤によるものであり、Terminal で何ができて何ができないのかまだわかりません。

4

3 に答える 3

4

これを達成する方法はたくさんあります。

古いスタンバイが最も強力であることがよくありますsedawk

ls | sed -rne 's:^([0-9]{4})(NAME)$:mv -iv & \1/\2:p'

コマンドが正しく表示されていることに満足したら、コマンド ラインをシェルにパイプします。

ls | sed -rne 's:^([0-9]{4})(NAME)$:mv -iv & \1/\2:p' | sh

NAME を角かっこで囲んで使用\2したので、例が示すよりも大きく変化する場合は、ファイル名をより適切に処理するための正規表現を考え出すことができます。

gawk(GNU awk、ほとんどの GNU/Linux ディストリビューションに見られるバリアント) で同じことを行うには:

ls | gawk '/^[0-9]{4}NAME$/ {printf("mv -iv %s %s/%s\n", $1, substr($0,0,4), substr($0,5))}'

最初のサンプルと同様に、これはコマンドを生成します。コマンドが意味をなす場合は| sh、行末に追加することでシェルを介してパイプできます。

これらすべてのmvコマンドに、オプション-i-vオプションを追加したことに注意してください。これはあなたの保護のためです。mv(Linux ターミナルで入力して)のマニュアル ページを読んで、man mvそれらを省略しても問題ないかどうかを確認してください。

また、これらの行では、すべてのディレクトリが既に存在すると想定しています。彼らがそうするかどうか、あなたは言及しませんでした。そうでない場合は、ディレクトリを作成するためのワンライナーを次に示します。

ls | sed -rne 's:^([0-9]{4})(NAME)$:mkdir -p \1:p' | sort -u

他の場合と同様に、追加| shしてコマンドを実行します。

の出力を解析する代わりに、for(ティムの回答で)のような構造を使用することが一般的に推奨されることに言及する必要があります。とはいえ、ファイル名の形式が のように単純な場合は、簡単なワンライナーが適していると思います。findls/[0-9]{4}word/sed

最後に、NAMEリテラル文字列「NAME」ではなく「任意の文字列」を実際に意味する場合は、上記のすべての例NAME.*.

于 2012-04-17T03:46:48.983 に答える
1

ターミナル アプリケーションを開き、cd移動/名前変更するファイルを含むディレクトリに移動し、これらのコマンドをコピーしてコマンド ラインに貼り付けます。

for file in [0-9][0-9][0-9][0-9]*; do
  dirName="${file%%*([^0-9])}"
  mkdir -p "$dirName"
  mv "$file" "$dirName/${file##*([0-9])}"
done

これは、名前を変更して移動するすべてのファイルが同じディレクトリにあることを前提としています。ファイルのグロビングでは、ファイル名の先頭に少なくとも 4 桁があることも前提としています。数字が 4 つ以上の場合でもキャッチされますが、4 つ未満の場合はキャッチされません。4 つ未満の場合は[0-9]、最初の行から適切な数の を削除します。

「NAME」(つまり、必要な新しいファイルの名前)が数字で始まる場合は処理されません。

bash での文字列操作の詳細については、このサイトを参照してください。

于 2012-04-17T03:25:02.513 に答える
1

次のスクリプトがこれを行います。スクリプトをリモート マシン上のファイルにコピーします (これを sortfiles.sh と呼びます)。

#!/bin/bash

# Get all files in current directory having names XXXXsomename, where X is an integer
files=$(find . -name '[0-9][0-9][0-9][0-9]*')

# Build a list of the XXXX patterns found in the list of files
dirs=
for name in ${files}; do
  dirs="${dirs} $(echo ${name} | cut -c 3-6)"
done

# Remove redundant entries from the list of XXXX patterns
dirs=$(echo ${dirs} | uniq)

# Create any XXXX directories that are not already present
for name in ${dirs}; do
  if [[ ! -d ${name} ]]; then
    mkdir ${name}
  fi
done

# Move each of the XXXXsomename files to the appropriate directory
for name in ${files}; do
  mv ${name} $(echo ${name} | cut -c 3-6)
done

# Return from script with normal status
exit 0

コマンドラインから、chmod +x sortfiles.sh

でスクリプトを実行します./sortfiles.sh

于 2012-04-17T03:06:53.507 に答える