Linux

ファイルのなかみをみる、ファイルの操作をする

ファイルのなかみをみる、ファイルの操作をする

備忘録の一種です。
なんだか書いてるうちに量が増えてしまいました。長くて申し訳ございませぬ。
(エディタの話は書いてないので別途でどうぞ。vimならvimtutorとうつと練習画面が出ます。)

・まずファイルの種類を知る

file file.txt
実行可能なファイルなのか、バイナリなのか読めそうなのか等がわかる

・ファイルの一般的な情報を表示する

ls -lrt file.txt

ファイルの権限や所有者やディレクトリなのかファイルなのかサイズはどのくらいかをみる

・ファイルが大きすぎるとき頭の一部分だけ表示してみる

head -10 file.txt

・ファイルが大きすぎるとき最後のほうの一部分だけ表示してみる

tail -10 file.txt

・ログファイルを更新を取り込みながら見続けるには

tail -f file.txt

・moreとlessとviewの違い

more file.txt

less -r file.txt

view file.txt

moreは改行が見づらいとか途中で落ちるとswpファイルが残るとか重いとか検索途切れるとかあるけど
大き目のファイルを読むときにあきらめやすいとかもある模様。
lessは早いとか検索しやすいとかは言われるがでかいの見るときにつらいという噂も。
viewは実は:w!で強制上書きが可能だったりする

・特定の内容がかいてあるかを調べる

grep '文字列' file.txt

・ファイルの行数をしらべる

wc -l file.txt

・ファイルのタイムスタンプを変える

hoge.fileのタイム・スタンプを現在の時間に変更する
$ touch hoge.file

hoge.fileのタイム・スタンプを2003年1月1日の00:00:00に変更する
$ touch -d "2003/1/1 00:00:00 am" hoge.file

(sudoするとsecureにログが残るし個人のhistoryにもコマンドは残る)

・ファイルの共有ライブラリをしらべる

ldd filename
どのライブラリに依存してるか表示されます。
ソースからmake installしたあとに確認に使うケース以外をよく知らない。
みためライブラリのパスとおってなかったら通す用途などに。
http://www.8wave.net/ldconfig.html

・ディレクトリを移動する
cd
pushd
popd
・特定の内容が書いてあるファイルを探す

find ./ -print |xargs grep '文字列'

場所と文字列は任意に指定する

・特定の名前のファイルを探す

find ./ -name "*hoge*" -print

ダブルクォートでくくると正規表現を認識してくれるが
シングルクォートだと特殊文字も文字列として解釈される(たぶん)

・日本語がファイル名についてるファイルを探す
# find ./ -name [^\x00-\x7F]*
./あああ.txt

http://so-zou.jp/software/tech/programming/tech/regular-expression/meta-character/variable-width-encoding.htm

・空白が含まれるファイルを探す

http://sea-otter-factory.blogspot.jp/2008/07/unix-xargs.html
http://d.hatena.ne.jp/yamamucho/20090923/1253708318
http://qiita.com/daei/items/76635f9fbf25824b525e

・ファイルの権限を変える

chmod -R 777 file.txt

-Rでディレクトリを指定した場合は再帰的にその下のファイルも権限が変わる。
権限については詳しくは"linux file パーミッション"などでググるとよいでしょう。

・ファイルの所有者を変える

chown root. -R file.txt

username.はusername.groupnameと同じ。上記の例だとuserおよびグループ所有者が両方ともrootになる。

・ユーザが作るファイルの権限をあらかじめ調整する

skelとかprofileで可能になる。

・標準入力からヒアドキュメントでファイルをつくる

catコマンドとリダイレクトを使います

cat > file.txt <<EOF
hoge
fuga
piyo
EOF
・ファイルの名前を変える

srcfilnameからdestfilnameに変える

mv srcfilename destfilename

ちょっとだけ正規表現で名前を変える

mv /etc/my.cnf{,.org}

一括で置換する

find . -name "*__keyword__*" | sed 'p;s/__keyword__/__replace_keyword__/g' | xargs -n2 mv
・ファイルをアーカイブする
cd ${JENKINS_HOME}
tar zcf ${JENKINS_BKUP_DIR}/${ARCHIVE_DATA} --exclude-from=${EXCLUDE_FILE} .
・アーカイブに別のファイルを追加する
tar cf hoge.tar ./hoge
tar rf hoge.tar ./fuga
・アーカイブファイルを展開する
tar xvzf hoge.tar.gz 
・アーカイブしたファイルに入ってるファイルを知る
tar tf hoge.tar
tar tzf hoge.tar.gz
・パスワード付きの圧縮ファイルをつくる

zip -e -P hogehoge -r hoge.zip hoge

・パスワード付きの圧縮ファイルを解凍する

unzip -P hogehoge hoge.zip

ディレクトリ指定で解凍する場合は-dをつける

unzip -P hogehoge -d dir1 hoge.zip

・差分パッチファイルを作る
・ディレクトリ丸ごと比較した差分パッチファイルを作る
diff -crN bash-4.1.org bash-4.1 > ${HOME}/rpmbuild/SOURCES/bash-syslog_facirity.patch
・特定の容量でファイルの分割をする
$ seq 1 10000 >> hoge 2>&1
$ ls -lh hoge
-rw-r--r-- 1 root root 48K  3月 15 16:19 2017 hoge
$ split --line-bytes=24k hoge fuga
$ ls fuga*
fugaaa  fugaab
$ tail -1 fugaaa
5136
$ head -1 fugaab
5137

https://linuxjm.osdn.jp/info/GNU_coreutils/coreutils-ja_33.html

・特定の文字列でファイルの分割をする
csplit dumpfile '/DROP TABLE IF EXISTS/' {*}

http://qiita.com/toshiro3/items/7844d45076b83103c095

・ファイルをおおざっぱに連結する

横につなげるなら

paste -d "," file1 file2

縦につなげるなら

cat file1 file2
・ファイルをカラムを指定して連結する
join -a 1 -j1 1 -j2 2 -t : -o 1.1,1.2,1.3,2.2,2.3 txt1 txt2 > file

1番目のファイルは一致しない部分も全て出力、キーのフィールドは1、2番目のファイルのキーのフィールドは2。
区切り文字を指定して、出力するフィールドを指定、引数ファイルを並べて出力ファイルにリダイレクトする。
sortしてからjoinしないと大体失敗する。

・ファイルをコピーする
cp <source-file> <dest-file>
・ファイルを置き換える
mv <source-file> <dest-file>
・ファイルの中身を置換する
sed -e 's/^ //g' -e 's/ \{1,100\}/,/g' file-a > file-b

file-aの先頭のスペースを全行削除して1~100までの連続したスペースをカンマひとつに変換しfile-bに出力する。
sの前に行数を指定することもできる。
※同じこと(スペースをまとめる)がtr -s ' 'でできます。

sed -e '5,10d' file
ファイルの5行目から10行目を削除する

sed '/^$/d' sample.txt 
空白行を消す

sed -e '/error/i ##check-line###' log.file
ログファイルにerrorがあったらチェックラインを追加

sed -i 's/enabled = 1/enabled = 0/g' /etc/yum.repos.d/rpmforge.repo
直接中身を書き換えている(iオプションの後ろに.bkなどのサフィックスを指定するとバックアップファイルが作られます)

head -1 log |sed 's/ [^ ]*@/ XXX@/g'
2010/04/01 00:00:24 sent 30000 XXX@softbank.ne.jp 123.123.60.252 XXX@hoge.net
メールログっぽいもののアカウントをマスクしてる(調査依頼時用)
[^ ]はスペース以外のすべての文字列と記号をあらわす正規表現。

ec2-describe-instances -K ./pk-oscaws.pem -C ./cert-oscaws.pem --region ap-southeast-1 --show-empty-fields |sed -e 's/, \{0,10\}/,/g' -e 's/\t\{1,100\}/,/g' -e 's/^TAG,[^ ]\{1,100\}/&\n-------------------------------/g'
カンマとスペースを全角スペースに変えてタブをカンマにしてTAGから始まる次の行に区切り線を入れてる。
sedの中で使う&(アンパサンド)は一致した文字列の引用を表す。

ある文字列を特定行に挿入する
sed -e "2i hoge" test.txt 
sed -e "2a hoge" test.txt
"line2"の行前に挿入
sed -e "/^line2$/i hoge" test.txt
http://d.hatena.ne.jp/rx7/20110310/p1

・viでも置換ができる(編集モードで)
:%s/aaa/bbb/g
aaaに当てはまるものすべてをbbbに置換

:1,3s/bbb/ccc/g
1~3行目のbbbをcccに置換

sedでのアドレス指定
 3 3行目
 20,$ 20行目から最終行まで
 10,5 10行目(2番目の数字が小さい場合)
 /^[0-9]/ 先頭が数字の行全て
 15,/Z$/ 15行目から最終文字がZで終わる行まで
 5,10! 5~10行目以外の行(1~4行目と11~最終行)

行番号を出すには、、
:set nu
行番号を消すには、、
:set nonu
・ファイルの中身を並べ替える
sort -u file
重複する文字列をひとつにして昇順に並び替える

sort -t : -k 2.2n,2.10n file1 > file2
区切り文字を指定して、キーは第2フィールドの2番目の文字から10番目の文字として並べかえる。nで数値として並べかえる。

grep "26/Feb/2007:02" access_log.2007-02-26|awk '{print $2}'|sort|uniq -c|sort -r|more
アクセスログの特定の時間をgrepしてIPをawkで出してuniq -cでカウントしてsort -r で多い順表示
・ファイルのシンボリックリンクを作る
ln -s <source-file> <dest-file>
・ファイルのハードリンクを作る
ln <source-file> <dest-file>
・ファイルのiノードを確認する
df -ih
・ファイルをリモートに転送する
scp -Cpr -i ~/.ssh/private_key_name ./localfile_or_dir remote_user@remote_host:/remote_path/
・指定した以上巨大なファイルを検索する
find /home -size +10000k -exec ls -lh {} \;
・指定日以前に作られたファイルを探して消す

よくログの切り回し後の旧いのを消すときなどに用いられる定番。

find ./ -name "hoge*.log" -ctime +10 -exec rm -f {} \;

find ./ -name "hoge*.log" -ctime +15 | xargs rm -f 

find ./ -name "hoge*.log" -ctime +28 -delete

など

・ログを出力させる

1行ずつリダイレクトする、世代管理して古いのは消す

LOG=/opt/log/bk.log
echo "`date +%Y%m%d.%H%M%S` daily backup start." >> ${LOG}
DAY=`date +%m%d`
if [ $DAY = "0101" ]
  then
    OY=`date -d '1 year ago' +%Y`
    mv $LOG $LOG.$OY
    find /opt/log -name "$LOG.*" -type f -atime +730 -exec rm -f {} \;
fi

後続の標準出力と標準エラー出力をまるっとファイルに出力する

  # log redirect.
  exec >> ${backup_log}
  exec 2>&1

loggerコマンド を使い任意のファシリティとプライオリティを指定してログを出力する

logger -ip [facility].[priority] [message]

logger -ip local0.emerg  'hello world'
・ログファイルを切り回す

とりあえず一般的な方法を。

findできりまわす
## rotate logs.
find /opt/log -name bk.log -size +1G -exec mv bk.log{,.$(/bin/date +%Y%m%d)} \;
find /opt/log -name "bk.log.*" -atime +365 -delete

上記は、
1GB以上のサイズのnameで指定したファイル名のファイルを日付つけてmvする
指定した日付より古い指定したファイル名のファイルを消す、という例です。
https://linuxjm.osdn.jp/html/GNU_findutils/man1/find.1.html

logrotated をつかう(長いです)

http://www.atmarkit.co.jp/flinux/rensai/linuxtips/747logrotatecmd.html
http://piyolian.blogspot.jp/2012/06/apache-not-reload-but-graceful-when.html

/var/logの下にログが出てる場合

syslogの世代1か月保持から1年保持に増やす
rotate 4→53

追加で切りまわす
/etc/logrotate.d/syslogと同じでよければそこに追加、
世代数など替えたければコピーして書き変える

example
要件:
 syslogとapacheログ、mysqlログを1年保持、1年以上経過したものは削除してOK、昨日のログは圧縮でOK。
 syslogの保存期間を1年にする(全てのサーバ)

追記
# vi /etc/logrotate.d/syslog 
weekly
compress
rotate 53

※sharedscriptsの上の行に追記するよう注意

# logrotate -d /etc/logrotate.d/syslog

logrotate.conf
logroteateは設定ファイル/etc/logrotate.confと/etc/logrotate.dディレクトリにある各設定ファイルで行います
以下がlogrotate.confファイルのデフォルトの設定です。

# see "man logrotate" for details
# rotate log files weekly
weekly ①

# keep 4 weeks worth of backlogs
rotate 4 ②

# create new (empty) log files after rotating old ones
create ③

# uncomment this if you want your log files compressed
#compress ④

# RPM packages drop log rotation information into this directory
include /etc/logrotate.d ⑤

# no packages own wtmp -- we'll rotate them here
/var/log/wtmp { ⑥
  monthly
  create 0664 root utmp
  rotate 1
}

# system-specific logs may be also be configured here.

それぞれの設定項目は以下の設定を表していて、ローテーションのグローバルな設定を行うことができます

① 毎週ごとにファイルのローテーションを行う(monthly、dailyも指定可)
② 4世代分のファイルを保存
③ ローテーションの際、新しいログファイルをすぐに作成する
④ ローテーションしたファイルを圧縮する
⑤ 各ログの詳細設定ファイルは/etc/logrotate.dディレクトリ以下に設定
⑥ /var/log/wtmp の設定を定義、wtmpファイルは毎月ローテーションし(1行目の設定を上書きしています)ローテーション後すぐ作成されるファイルのパーミッションを0644、所有者をroot、グループをutmpとする上でファイルを 1 つだけ保存する

logrotate.dディレクトリ以下の設定
各ログファイルごとの設定は、/etc/logrotated.dディレクトリの中に設置された設定ファイルで行います
syslogdで設定されたログの設定ファイルは、/etc/logrotated.d/syslogになります。

デフォルトのsyslogファイル(/etc/logrotated.d/syslog)
/var/log/messages /var/log/secure /var/log/maillog /var/log/spooler /var/log/boot.log /var/log/cron {
  sharedscripts
  postrotate
    /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
  endscript
}

このファイルでは一行目にどのログファイルに関する設定かの記述がされています。
複数のログファイルのローテーション後に、下の行の処理を1度だけ実行した後syslogdの動作中にファイルを移動すると、syslogdは出力すべきログファイルを見失ってしまうため、syslogdにHUPシグナルを送って設定を再読み込みさせコマンドを終了しています。

以下は設定ファイルで利用できる

記述 解説
create [パーミッション] [ユーザ名] [グループ名] 指定したファイル情報でローテート後に新たな空のログファイルを作成
daily 毎日ローテート
weekly 毎週ログローテートする
monthly 毎月ローテートする
ifempty ログファイルが空でもローテートする
missingok ログファイルが存在しなくてもエラーを出力しない
nocompress ローテートされたログを圧縮しない
nocreate 新たな空のログファイルを作成しない
nomissingok ログファイルが存在しない場合エラー出力する
noolddir ローテーション対象のログと同じディレクトリにローテートされたログを格納する
notifempty ログファイルが空ならローテートしない
olddir ディレクトリ名 指定したディレクトリ内にローテーションされたログを格納する
postrotate~endscript postrotateとendscriptの間に記述されたコマンドをログローテート後に実行
prerotate~endscript postrotateとendscriptの間に記述されたコマンドをログローテート前に実行
rotate 回数 指定した回数だけローテートする
size ファイルサイズ 指定したファイルサイズ以上であればローテートする
sharedscripts 複数指定したログファイルに対してpostrotateまたはprerotateで記述されたコマンドを実行

以下はhttpdのアクセスログとエラーログのローテート設定例です

/usr/local/apache2/logs/access_log /usr/local/apache2/logs/error_log {
   weekly
   rotate 4
   missingok
   sharedscripts
   postrotate
      /bin/killall -HUP `cat /usr/local/apache2/logs/httpd.pid 2>/dev/null` 2> /dev/null
   endscript
} 

*/usr/local/apache2/logs/access_logと/usr/local/apache2/logs/error_logについて定義
*一週間に一度ローテート
*ファイルが存在しなくてもエラーを出さない
*/usr/local/apache2/logs/access_logと/usr/local/apache2/logs/error_logに対してコマンドを実行
*ローテート後に/bin/killall -HUPコマンドを実行する

★確認コマンド
・ログローテート登録されてるか確認するコマンド

# logrotate -d /etc/logrotate.d/syslog
# logrotate -d /etc/logrotate.d/mysqld
# logrotate -d /etc/logrotate.d/hb_pmon 
reading config file /etc/logrotate.d/hb_pmon
reading config info for /var/log/heartbeat_process_monitor.log 

Handling 1 logs

rotating pattern: /var/log/heartbeat_process_monitor.log weekly (4 rotations)
empty log files are rotated, old logs are removed
considering log /var/log/heartbeat_process_monitor.log
log does not need rotating
not running postrotate script, since no logs were rotated

・最後にいつ切りまわされたか確認する

# cat /var/lib/logrotate.status 
logrotate state -- version 2
"/var/log/acpid" 2010-3-12
"/var/log/conman/*" 2010-3-12
"/var/log/cups/error_log" 2010-3-17
"/var/log/mgetty.log.tty[^.]" 2010-3-12
"/var/log/mgetty.log.tty[^.][^.]" 2010-3-12
"/var/log/mgetty.log.tty[^.][^.][^.]" 2010-3-12
"/var/log/mgetty.log.tty[^.][^.][^.][^.]" 2010-3-12
"/var/log/mgetty.log.tty[^.][^.][^.][^.][^.]" 2010-3-12
"/var/log/mgetty.log.tty[^.][^.][^.][^.][^.][^.]" 2010-3-12
"/var/log/mgetty.log.tty[^.][^.][^.][^.][^.][^.][^.]" 2010-3-12
"/var/log/mgetty.log.tty[^.][^.][^.][^.][^.][^.][^.][^.]" 2010-3-12
"/var/log/mgetty.log.tty[^.][^.][^.][^.][^.][^.][^.][^.][^.]" 2010-3-12
"/var/log/mgetty.log.tty[^.][^.][^.][^.][^.][^.][^.][^.][^.][^.]" 2010-3-12
"/var/log/mgetty.log.unknown" 2010-3-12
"/var/log/mgetty.callback" 2010-3-12
"/var/log/ppp/connect-errors" 2010-3-12
"/var/account/pacct" 2010-3-12
"/var/log/rpmpkgs" 2010-6-20
"/var/log/messages" 2010-6-20
"/var/log/secure" 2010-6-20
"/var/log/maillog" 2010-6-20
"/var/log/spooler" 2010-6-20
"/var/log/boot.log" 2010-6-20
"/var/log/cron" 2010-6-20
"/var/log/wpa_supplicant.log" 2010-3-12
"/var/log/yum.log" 2010-3-12
"/var/log/wtmp" 2010-3-12
"/var/log/munin/munin-update.log" 2010-5-14
"/var/log/munin/munin-graph.log" 2010-5-14
"/var/log/munin/munin-html.log" 2010-5-14
"/var/log/munin/munin-limits.log" 2010-5-14
"/var/log/munin/munin-node.log" 2010-6-23
"/var/log/ha-debug" 2010-6-20
"/var/log/ha-log" 2010-6-20
"/var/log/ldirectord.log" 2010-6-20
"/var/log/zabbix/zabbix_agentd.log" 2010-6-4
"/var/log/heartbeat_process_monitor.log" 2010-6-23

# ls -l /var/log/heartbeat_process_monitor.log*
-rw-r--r-- 1 root root 13034042 6月 23 11:46 /var/log/heartbeat_process_monitor.log
・ハードディスクのファイルを跡形もなく消す
# dd if=/dev/urandom of=/dev/hda
# dd if=/dev/urandom of=/dev/hda
# dd if=/dev/zero of=/dev/hda

https://www.slogical.co.jp/tech/sysop_ddhddclear.html

・ファイルを暗号化・復号化する

http://ameblo.jp/itboy/entry-10484615897.html