在 Shell 裡面直接執行 Python 跟 PHP 指令
bash 可以直接在提示符號後面輸入複雜的指令工作,很多時候很方便做一些日常工作。
# 印出每個 csv 檔案的頭四行
$ for file in *.csv; do echo === $file ===; head -4 $file; done
AWK 在使用時也可以直接在指令列輸入內容。
# 輸出第三欄跟第四欄的總和
$ cat large.csv | awk '{male += $3; female+=$4} END{print male, female}'
PHP 跟 Python 其實也提供了類似的用法。輸入指令的時候 ;
之類的字元不能省略,如同正常寫 script 一樣,語法必須正確。
# 把檔案每一行都 urlencode 然後印到畫面上
$ cat large2.txt | php -r 'while($line = fgets(STDIN)){ echo urlencode($line),"\n"; }'
# 單純印出每一行,當然可以塞入更多邏輯
$ cat large2.txt | python3 -c '
> import sys
> for line in sys.stdin: print(line)
> '
注意 Python 雖然可以寫成單行流,但實用上沒那麼方便。
# 這樣可以
$ python3 -c 'for i in range(5): print(i**2 if i % 2 == 0 else i)'
0
1
4
3
16
# 這樣也可以
$ python3 -c 'import json; print(json.dumps({"a":1}))'
{"a": 1}
# 這樣不行
$ python3 -c 'import json; for i in range(5): print(json.dumps({"a":i}))'
File "<string>", line 1
import json; for i in range(5): print(json.dumps({"a":i}))
^
SyntaxError: invalid syntax
當然也可以用這種方法把 Python 或 PHP 安插在 bash script 裡面。可讀性就要想一下怎麼控制,寫太長的話會不容易閱讀與維護。
#!/bin/bash
# 把 csv 檔案轉換成多個 PHP 陣列並分開存檔
# 沒有特別意義就是個示範
data_file=$1
zcat "$data_file" \
| grep -v 'LINE_TO_REMOVE' \
| php -r '
while ($line = fgets(STDIN)) {
$line = trim($line);
$fields = explode(",", $line);
$id = $fields[0];
$file = sprintf("%s/data_%d.php", __DIR__, $id);
$content = "<?php return " . var_export($fields, true) . ";";
file_put_contents($file, $content);
}'