Get a subset of several alphabetically ordered files in Bash [closed] - linux

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
Let's assume I have a group of files "aab.md", "aac.md", "aad.md" ... "csdw.md". Content/filenames are actually in (non-latin) utf-8. They can be sorted alphabetically.
How can I get in Bash a subset of those files starting with e.g. "aad.md" and upwards?

declare -a files
while IFS= read -r -d $'\0' file; do
filename=${file##*/}
if [[ ! "$filename" < "aad.md" ]]
then
files=("${files[#]}" "$file")
fi
done < <(find . -name "*.md" -print0)
The array "${files[#]}" should now contain paths to files whose basename is greater than aad.md.
This uses a number of less well-known techniques in bash: arrays, prefix substitution, zero-terminated records (and their reading), and process substitution; so don't hesitate to ask if something is unclear.
Note that bash [[...]] construct doesn't know about >= operator, so we need to improvise with ! ...<....
This is almost pure bash, no external commands except find. If you accept external commands, $(basename $file) is more obvious than ${file##*/}, but at that point you might as well use awk... and if you can use awk, why not Ruby?
ruby -e "puts Dir['**/*.md'].select{|x| File.basename(x) >= 'aad.md'}"

Related

paste data based on certain condition [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
experts i have many files in a directory and these files contain some numerical numbers.
Probably not POSIX-compatible; tested on Bash 5.0. Assuming that the filenames don't contain whitespaces and have fixed length.
for file_with_a in *A.??
do
target_left=${file_with_a:0:15} # e.g., 2019__01_NDV.NT
target_right=${file_with_a:16:3} # e.g., .AS
cat $target_left[A-C]$target_right > ${target_left}_ABC$target_right
done
With mapfile aka readarray which is a bash4+ feature.
#!/usr/bin/env bash
files=([0-9][0-9][0-9][0-9]__*[ABC]*.??)
while mapfile -d '' -n3 array && ((${#array[*]} == 3)); do
if [[ ${array[0]%%_*} == ${array[1]%%_*} && ${array[0]%%_*} == ${array[2]%%_*} ]]; then
paste "${array[0]}" "${array[1]}" "${array[2]}" > "${array[0]%${array[0]:(-4)}}_ABC.${array[0]:(-2)}"
fi
done < <(printf '%s\0' "${files[#]}")

How to print output twice in Linux? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
Which command is use to print the file name twice on output?
I want to write a pipe that List all the files beginning with the character ā€˜Pā€™ on the screen twice in succession.
Something like:
ls -1 | while read i ; do echo $i $i ; done
ā€¦ should do the trick.
ls | sed -E 's/^(P.*)/\1 \1/'
ls, when used with a pipe, puts 1 file per line.
We use sed with extended RE support -E.
We capture the name of any word beginning with P: ^(P.*)
and replace it with itself, a space, followed by itself \1 is a back-reference to what is captured in the parenthesis ( ... ) .
I suggest to use the find utility:
find . -maxdepth 1 -type f -name 'P*' -print -print

Create mutiple files in multiple directories [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I 've got tree of folders like:
00 -- 0
-- 1
...
-- 9
...
99 -- 0
-- 1
...
-- 9
How is the simplest way to create in every single subfolders a file like:
/00/0/00_0.txt
and save to every files some kind of data?
I tried with touch and with loop but without success.
Any ideas how to make it very simple?
List all directories using globs. Modify the listed paths with sed so that 37/4 becomes 37/4/37_4.txt. Use touch to create empty files for all modified paths.
touch $(printf %s\\n */*/ | sed -E 's|(.*)/(.*)/|&\1_\2.txt|')
This works even if 12/3 was just a placeholder and your actual paths are something like abcdef/123. However it will fail when your paths contain any special symbols like whitespaces, *, or ?.
To handle arbitrary path names use the following command. It even supports linebreaks in path names.
mapfile -td '' a < <(printf %s\\0 */*/ | sed -Ez 's|(.*)/(.*)/|&\1_\2.txt|')
touch "${a[#]}"
You may use find and then run commands using -exec
find . -type d -maxdepth 2 -mindepth 2 -exec bash -c 'f={};
cmd=$(echo "${f}/${f%/*}_${f##*/}.txt"); touch $cmd' \;
the bash substitution ${f%/*}_${f##*/} replaces the last / with _

How to loop over a list containing two different pattern files in linux (bash)? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I got a list containing filenames that match the following two patterns:
one is like XXX_01.fastq
another is XXX_01_001.fastq
I am going to write a for loop (in bash) to loop over all the filenames with different patterns and I need to determine which ones match the patterns above. Any help about it?
Contents of list.txt:
$ cat list.txt
AAA_01.fastq
AA_01_001.fastq
BBB_01_002.fastq
BBB_02.fastq
Example using bash pattern matching:
for file in `cat list.txt`; do
if [[ $file =~ [A-Z]{3}_[0-9]{2}\.fastq || $file =~ [A-Z]{3}_[0-9]{2}_[0-9]{3}\.fastq ]]; then
echo "MATCH $file";
fi;
done
Output:
MATCH: AAA_01.fastq
MATCH: BBB_01_002.fastq
MATCH: BBB_02.fastq

Grep script to run on CD [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 9 years ago.
Improve this question
Im trying to learn some bash script writing and cleaning out some old CDs (remember those?)
What I have is a bunch of backup CDs with no rhyme or reason to them so I'd like to create a grep script that will search them based on keywords. (I'm currently trying to test the script first against the desktop) I know how to run grep, but its the scripting I'm having trouble with.
So here's what I have:
#!/bin/bash
#CDGrepScript
SOURCEDIR=/home/name/Desktop (I'm currently testing it with files on the desktop)
#mount /dev/cdrom
#SOURCEDIR=/dev/cdrom
echo "hello, $USER. I will search your files"
echo Begin Search...
grep -ir "taxes|personal|School" *
echo $results
echo "The search is complete. Goodbye"
exit
Now when I run this against files on the desktop. My script hangs after "Begin search" What am I doing wrong?
Thanks for the help
You might be served better by a more general tool. Like a rgrep (recursive grep) that will walk through a tree searching for a search term. An example:
# rgrep
#
# Search for text strings in a directory hierarchy
set +x
case $# in
0 | 1 )
# Not enough arguments -- give help message
echo "Usage: $0 search_text pathname..." >&2
exit 1
;;
* )
# Use the first argument as a search string
search_text=$1
shift
# Use the remaining argument(s) as path name(s)
find "$#" -type f -print |
while read pathname
do
egrep -i "$search_text" $pathname /dev/null
done
;;
esac
Put this in your path, then you just change directories to the mount point for the CD-ROM, and type
$ rgrep "taxes" .
Or whatever other search you wish to perform.

Resources