ดังนั้นฉันจะมีไดเรกทอรีที่มีไฟล์มากมายเช่น g.txt ซึ่ง g.txt ได้รับการแก้ไขครั้งล่าสุดเมื่อวันที่ 20 มิถุนายน 2012
ฉันจะเปลี่ยนชื่อแบทช์ไฟล์ทั้งหมด (เช่น g.txt) ด้วยวันที่แก้ไขล่าสุดของวันที่ 20 มิถุนายน 2012 ต่อท้ายได้อย่างไร
ดังนั้นฉันจะมีไดเรกทอรีที่มีไฟล์มากมายเช่น g.txt ซึ่ง g.txt ได้รับการแก้ไขครั้งล่าสุดเมื่อวันที่ 20 มิถุนายน 2012
ฉันจะเปลี่ยนชื่อแบทช์ไฟล์ทั้งหมด (เช่น g.txt) ด้วยวันที่แก้ไขล่าสุดของวันที่ 20 มิถุนายน 2012 ต่อท้ายได้อย่างไร
คำตอบ:
Bash หนึ่งซับอย่างรวดเร็วและสกปรกเพื่อเปลี่ยนชื่อไฟล์ทั้งหมด (แบบกลม) ในไดเรกทอรีปัจจุบันจากfilename.txt
เป็นfilename.txt-20120620
:
for f in *; do mv -- "$f" "$f-$(stat -c %Y "$f" | date +%Y%m%d)"; done
Bash nerd ที่กล้าได้กล้าเสียจะพบว่ามีขอบตัวเรือนบางอย่างที่จะทำลายมันฉันแน่ใจ :)
เห็นได้ชัดว่าสิ่งนี้ไม่ได้ทำสิ่งที่ต้องการเช่นการตรวจสอบว่าไฟล์มีบางสิ่งที่ดูเหมือนวันที่สิ้นสุดอยู่แล้ว
date
การใช้งานประเภทใดนั้น GNU ของฉันdate
ดูเหมือนจะไม่จัดการกับอินพุต
นี่คือเวอร์ชั่นหนึ่งของสายการบินเดียวของ goldschrafe ที่:
เช่นเดียวกันกับชื่อไฟล์ที่ขึ้นต้นด้วยเส้นประ
for f in *; do mv -- "$f" "$f-$(date -r "$f" +%Y%m%d)"; done
date -r "$f" +%Y%m%d
ฉะนั้นมันจะไม่ทำงานหากPOSIXLY_CORRECT
อยู่ในสภาพแวดล้อม โดยทั่วไปตัวเลือกควรดำเนินการก่อนอาร์กิวเมนต์อื่น ๆ
"${f}"
แน่นอนคุณไม่จำเป็นต้องจัดฟันใน
zsh แบบบังคับด้านหนึ่ง (ไม่นับการโหลดครั้งเดียวของส่วนประกอบเสริม):
zmodload zsh/stat
autoload -U zmv
zmv -n '(*)' '$1-$(stat -F %Y%m%d +mtime -- $1)'
เราใช้stat
builtin จากzsh/stat
โมดูลและzmv
ฟังก์ชั่นเพื่อเปลี่ยนชื่อไฟล์ และนี่คือส่วนเพิ่มเติมที่ระบุวันที่ก่อนส่วนขยายหากมี
zmv -n '(*)' '$1:r-$(stat -F %Y%m%d +mtime -- $1)${${1:e}:+.$1:e}'
ตามที่ฉันเข้าใจเราไม่ทราบล่วงหน้าว่าวันที่แก้ไขคืออะไร ดังนั้นเราจำเป็นต้องได้รับจากแต่ละไฟล์จัดรูปแบบผลลัพธ์และเปลี่ยนชื่อไฟล์แต่ละวิธีเพื่อให้มีวันที่แก้ไขในชื่อไฟล์
คุณสามารถบันทึกสคริปต์นี้เป็นแบบ "modif_date.sh" และทำให้สามารถเรียกใช้งานได้ เราเรียกใช้ไดเรกทอรีเป้าหมายเป็นอาร์กิวเมนต์:
modif_date.sh txt_collection
โดยที่ "txt_collection" เป็นชื่อของไดเรกทอรีที่เรามีไฟล์ทั้งหมดที่เราต้องการเปลี่ยนชื่อ
#!/bin/sh
# Override any locale setting to get known month names
export LC_ALL=c
# First we check for the argument
if [ -z "$1" ]; then
echo "Usage: $0 directory"
exit 1
fi
# Here we check if the argument is an absolute or relative path. It works both ways
case "${1}" in
/*) work_dir=${1};;
*) work_dir=${PWD}/${1};;
esac
# We need a for loop to treat file by file inside our target directory
for i in *; do
# If the modification date is in the same year, "ls -l" shows us the timestamp.
# So in this case we use our current year.
test_year=`ls -Ggl "${work_dir}/${i}" | awk '{ print $6 }'`
case ${test_year} in *:*)
modif_year=`date '+%Y'`
;;
*)
modif_year=${test_year}
;;
esac
# The month output from "ls -l" is in short names. We convert it to numbers.
name_month=`ls -Ggl "${work_dir}/${i}" | awk '{ print $4 }'`
case ${name_month} in
Jan) num_month=01 ;;
Feb) num_month=02 ;;
Mar) num_month=03 ;;
Apr) num_month=04 ;;
May) num_month=05 ;;
Jun) num_month=06 ;;
Jul) num_month=07 ;;
Aug) num_month=08 ;;
Sep) num_month=09 ;;
Oct) num_month=10 ;;
Nov) num_month=11 ;;
Dec) num_month=12 ;;
*) echo "ERROR!"; exit 1 ;;
esac
# Here is the date we will use for each file
modif_date=`ls -Ggl "${work_dir}/${i}" | awk '{ print $5 }'`${num_month}${modif_year}
# And finally, here we actually rename each file to include
# the last modification date as part of the filename.
mv "${work_dir}/${i}" "${work_dir}/${i}-${modif_date}"
done
stat
ยูทิลิตี้อื่นหรือไม่มีเลย
ls
ไม่น่าเชื่อถือ ในตัวแปร unix บางชื่อผู้ใช้และกลุ่มสามารถมีช่องว่างซึ่งจะทำให้การจัดตำแหน่งคอลัมน์วันที่
ls
เป็นวันที่และเวลา (แทนที่จะเป็นวันที่และปี) จะต้องอยู่ในปีปัจจุบัน นี่ไม่เป็นความจริง. ในช่วงหกเดือนที่ผ่านมา ที่อาจเป็นในปีก่อนหน้า (เช่น 27 ก.ย. 2559 ถึง 31 ธ.ค. 2559 อยู่ในช่วงหกเดือนที่ผ่านมา) (6) ด้วยความเสี่ยงที่จะเกิดเรื่องไร้สาระกับวิกิพีเดียของ Greg (ซึ่ง @Gilles ได้อ้างถึงแล้ว) ชื่อไฟล์ที่มีบรรทัดใหม่และช่องว่างอาจทำให้สิ่งนี้ล้มเหลว … (ต่อ)
นี่คือเวอร์ชั่นของหนึ่งซับของคาสิโน (ขึ้นอยู่กับ goldschrafe ของ oneliner) ขยายด้วยidempotence ,
คือขยายไปยังไฟล์คำนำหน้าด้วยเวลาวันที่และการทำเช่นนี้เฉพาะสำหรับผู้ที่ยังไม่มีคำนำหน้าเวลาวันที่แต่สำหรับผู้ที่ไม่ได้มีคำนำหน้าวันเวลาเลย
ใช้ตัวพิมพ์: มีประโยชน์หากคุณเพิ่มไฟล์ใหม่ลงในไดเรกทอรีและต้องการเพิ่มคำนำหน้าเวลาวันที่ให้กับไฟล์ที่ยังไม่มี
for f in * ; do
if [[ "$f" != ????-??-??' '??:??:??' - '* ]]; then
mv -v -- "$f" "$(date -r "$f" +%Y-%m-%d' '%H:%M:%S) - $f" ;
fi;
done
for f in *.jpg ; do jhead -ft "$f" ; done
แหล่งที่มา: unix.stackexchange.com/a/290755/9689