Good day!
I was wondering how to print a specific letter of the following output:
ls -1 *Mcmm*txt *Mmmm*txt
It gives:
Mcmm_E.txt
Mcmm_M.txt
Mmmm_E.txt
Mmmm_M.txt
And I want to obtain:
E
M
E
M
Thanks in advance for any suggestion
You could try this. It prints the last-but-one field based on _
and .
as separators(assuming that you need to print everything between the last _
and .
and assuming that there is one instance of .
in each file name)
ls -1 *Mcmm*txt *Mmmm*txt | awk -F'_|\\.' '{print $(NF-1)}'
ls -1 *Mcmm*txt *Mmmm*txt | cut -b6
Is a lot less typing than using awk...
cut -b6
selects byte 6 of each line.
You should always avoid parsing ls
; see here . Use find
instead:
find . -type f -name '*M[cm]mm*.txt' -print0
And if you have gnu grep
, you could pipe into:
grep -oPz '[^_](?=.txt)'
Results:
E
E
M
M
Another awk
ls -1 *Mcmm*txt *Mmmm*txt | awk -F"[_.]" '{print $2}'
E
M
E
M
Do not parse the output of ls
. In your specific case, if you only want to print the sixth character of each file name matching your pattern, do:
files_ary=( *Mcmm*txt *Mmmm*txt )
for f in "${files_ary[@]}"; do
printf '%s\n' "${f:5:1}"
done
To only print the character in front of .txt
, a funny possibility is:
files_ary=( *Mcmm*.txt *Mmmm*.txt )
for f in "${files_ary[@]%.txt}"; do
printf '%s\n' "${f: -1}"
done
These methods are 100% pure bash, and they will work even if you have funny symbols in the file names (spaces, newlines, etc.). Oh, and to be 100% safe, don't forget to use globs with shopt -s nullglob
.
ls -1 *Mcmm*txt *Mmmm*txt | sed -u "s/^.\{5\}\(.\).*/\1/"
-u for stream treatment (avoir buffering on huge folder)
I think cut
will be faster
In this case, you don't take care of the first char even with a * in the ls
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.