質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.36%
bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

シェルスクリプト

シェルスクリプトは、UNIX系のOSもしくはコマンドラインインタプリタ向けに記述されたスクリプト。bash/zshといったシェルによって実行されるため、このように呼ばれています。バッチ処理などに使用されており、テキストファイルに書かれた命令を順に実行します。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

シェル

シェル(shell)はUnix や Linux 系のOSで使用されるコマンドインタプリタを指します。

置換

置換とは文字列中の特定の文字に対して、別の文字列に置き換えることを指します。

Q&A

解決済

4回答

1938閲覧

ファイル名の置換スクリプト

yakitori881

総合スコア2

bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

シェルスクリプト

シェルスクリプトは、UNIX系のOSもしくはコマンドラインインタプリタ向けに記述されたスクリプト。bash/zshといったシェルによって実行されるため、このように呼ばれています。バッチ処理などに使用されており、テキストファイルに書かれた命令を順に実行します。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

シェル

シェル(shell)はUnix や Linux 系のOSで使用されるコマンドインタプリタを指します。

置換

置換とは文字列中の特定の文字に対して、別の文字列に置き換えることを指します。

1グッド

0クリップ

投稿2020/04/28 02:44

編集2020/04/30 10:34

前提・実現したいこと

RHEL7.x にてバックアップするシェルスクリプトを作成しようとしています。

やりたいこととしては、
特定のフォルダに生成されたファイルが多数あります。
このファイルは命名規則があって
AAA_somu_YYYYMMDD.csv
AAA_keiri_YYYYMMDD.csv
BBB_keiri_YYYYMMDD.csv
CCC_somu_YYYYMMDD.csv

のように、
最初3文字、部門、日付といったファイル名になっています。
これをバックアップしたいのですが、ファイル名を置換させたいです。

AAA_somu_YYYYMMDD.csv → XXXX01AA.csv
AAA_keiri_YYYYMMDD.csv → XXXX02AA.csv
BBB_keiri_YYYYMMDD.csv → XXXX02BB.csv
CCC_somu_YYYYMMDD.csv → XXXX01CC.csv

ファイル名の先頭3文字を、後ろに2文字に置き換え(3文字目はカット)
somuは01、keiriは02にコード化させたいです。
先頭4文字は固定です。

ファイル数がたくさんあるため、シェルで回したいと思いますが
ファイル名の置換でつまづいてます。
renameコマンドの検討もしてみましたが、REHLではutil-linuxだったりして上手く行きませんでした。
どのような方法がとれますでしょうか。
お手数をおかけしますが、よろしくお願いいたします。

追加情報

皆様からいろいろご教授いただきありがとうございます。
申し訳ありませんがもう少し条件をつけさせてください。

各ファイルのディレクトリを別々に配置したいと思います。
最初3文字のディレクトリはファイル名の3文字と同一です。
必ず英文字で数字や記号は入りません。

/file/AAA/AAA_somu_YYYYMMDD.csv
/file/AAA/AAA_keiri_YYYYMMDD.csv
/file/BBB/BBB_keiri_YYYYMMDD.csv
/file/CCC/CCC_somu_YYYYMMDD.csv

個別でご質問いただいておりました日付に関しては、ファイル名リネーム後に空っぽにする処理を別途行っております。
生成されるファイル時点では必ず空になっている状態にしています。
/file/AAA
/file/BBB
/file/CCC
という状態になっています。

ご提示していただいた処理を、それぞれ試してみましたが上記のようなディレクトリ構成だと上手く行きませんでした。

mv: `AAA_somu_20200430.csv' を stat できません: そのようなファイルやディレクトリはありません
退会済みユーザー👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

bashでも文字列操作として、IFSとreadの組み合わせ等である程度はできます。
また、部門名からコードの変換は連想配列が使えます。

ここではechoに替えてますが、ls で出力された一覧からmvコマンドを構成するサンプルは次の通りです。
※AAAやBBBの所に_があるとアウトですが

なお、先頭が3文字、部門名が既知のもので、拡張子が csv というのはチェックを入れている ( 条件に合わなければ continue でスキップ ) のですが、ここを緩くするか厳しくするかはお好みでどうぞ。
※あと、日付をどうするかの判断はなんとも言えないところです。

sh

1declare -A OU_CODES 2OU_CODES[somu]=01 3OU_CODES[keiri]=02 4 5ls | while IFS=_. read t1 t2 t3 t4; do 6 [[ ${#t1} -eq 3 && $t4 = csv && -n $t2 ]] || continue 7 oucode="${OU_CODES[$t2]}" 8 [[ -n $oucode ]] || continue 9 echo "mv ${t1}_${t2}_${t3}.csv XXXX${oucode}${t1:0:2}.csv" </dev/null 10done

投稿2020/04/28 12:50

angel_p_57

総合スコア1681

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yakitori881

2020/05/01 02:49

ご教授いただきありがとうございます。こちらはカレントディレクトリでないと処理できないでしょうか?
angel_p_57

2020/05/01 04:30

このサンプルはカレントディレクトリで処理する例ですね。 「実行ディレクトリに関わらず」ということであれば、次のようにアレンジできます。 ``` ls $SOURCE_DIR | while … … mv $SOURCE_DIR/~ $DESTINATION_DIR/~ done ```
yakitori881

2020/05/01 12:05

ありがとうございました。ご提示いただいた方法ベースに実現できそうです。
guest

0

似たようなものですが、これの出力をシェルに流してください。
ファイル名のチェックはしていません。

bash

1#!/bin/bash 2declare -A dept=( [somu]=01 [keiri]=02 ) 3root=/file 4header=XXXX 5for f in $(find $root -type f -name '*_*_[0-9]*.csv') 6do 7 set $(echo ${f##*/} | (IFS=_ read f1 f2 f3; echo $f1 $f2)) 8 #mv $f ${f%/*}/${header}${dept[$2]}${1:0:2}.csv 9 echo "mv $f ${f%/*}/${header}${dept[$2]}${1:0:2}.csv" 10done

before

1file 2├── AAA 3│   ├── AAA_keiri_20200501.csv 4│   └── AAA_somu_20200501.csv 5├── BBB 6│   └── BBB_keiri_20200501.csv 7└── CCC 8 └── CCC_somu_20200501.csv

after

1file 2├── AAA 3│   ├── XXXX01AA.csv 4│   └── XXXX02AA.csv 5├── BBB 6│   └── XXXX02BB.csv 7└── CCC 8 └── XXXX01CC.csv 9

投稿2020/05/01 07:01

編集2020/05/01 09:12
aobaoba

総合スコア63

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yakitori881

2020/05/01 12:38

回答ありがとうございます。さまざまな方法があることをしれて、とても勉強になりました!次もご教示いただけたら幸いです。
guest

0

次のAWKスクリプトをrename.awkで保存しchmod 755 rename.awkしておきます。

awk

1#!/usr/bin/awk -f 2 3BEGIN { 4 FS = "_" 5 bushoMap["somu"] = "01"; 6 bushoMap["keiri"] = "02"; 7} 8length($1) >= 2 && $2 in bushoMap && $3 ~ /[0-9]{8}.csv/ {print "mv " $0 " XXXX" bushoMap[$2] substr($1,2) ".csv"}

次にファイル名を引き渡すとmvしてくれます。

ls *.csv | ./rename.awk | sh

一応AA_busho_NNNNNNNN.csvと言うファイル名の形式とbushoが既知かどうかチェックしていますが、実戦で使うにはもうちょっとエラーチェックが必要かもしれません。

ところで本当に日付は削っていいのですか?もしBBB_keiri_20200401.csvとBBB_keiri_20200402.csvがあったら両者ともXXXX02BB.csvになってしまいませんか?

投稿2020/04/28 05:21

編集2020/04/28 05:23
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yakitori881

2020/04/30 08:42

ご回答ありがとうございます。日付ごとにバックアップを取った後に空っぽにする処理を別途行っており、生成されるファイルの置き場所には、常に空っぽの状態にします。 バックアップ→削除処理(ここまでが前日)→フィアル生成→リネーム→バックアップ・・・という流れを想定しています。
yakitori881

2020/05/01 12:38

回答ありがとうございます。勉強になりました!次もご教示いただけたら幸いです。
guest

0

perlでシェルスクリプトを作るという方法を考えてみました。

ls *.csv | perl -ne 'BEGIN{%x=(somu=>"01",keiri=>"02")} chomp; $f=$_; s/(..)._([a-z]+)_.*/"XXXX".$x{$2}.$1.".csv "/e; print "mv $f $_\n"' | sh

シェルスクリプトを介さずともperlの中で処理を完結させることもできますが、実行する前に前後のステップの確認もしたいところでしょうし、perlに慣れていないならこのパターンが安全かなと思いました。

追記事項に対応し、なおかつ冗長なコードを整理

ls /file/*/*.csv | perl -pe 'BEGIN{%x=(somu=>"01",keiri=>"02")} chomp; $f=$_; s{(.*)/(..)._([a-z]+)_.*}{"mv $f $1/XXXX$x{$3}$2.csv"}e' > test.sh

できたtest.shをシェルスクリプトとして実行。

投稿2020/04/28 04:39

編集2020/04/30 11:23
KojiDoi

総合スコア13692

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yakitori881

2020/05/01 02:49

追加のご回答ありがとうございます。早速試しましたが、test.shを実行したところ mv: 宛先の `/file/AAA/XXXX02AA.csv' はディレクトリではありません となってしまいました。。。
KojiDoi

2020/05/01 04:32

私が想定しているのと状況が違うのでしょうか。 test.shの内容はどうなっていますか?
yakitori881

2020/05/01 12:37

ご回答ありがとうございます。 前の文字列と、mvが連続してしまっていました。 ですが、とてもためになりました!ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問