paste data based on certain condition [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 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[#]}")

Related

Bash how to replace nth character in a string [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 6 months ago.
Improve this question
I have a string with in a file:
"1.0.0.0.5";
I would like to replace 5 with 6 so the output should look like
"1.0.0.0.6";
could you please help me in this to achieve the output as above in bash
It seems to me that what you really want to do is increment the 5th dot-delimited field in that line.
line='"1.0.0.0.5";'
if [[ $line =~ \"([^\"]+) ]]; then
IFS="." read -ra fields <<< "${BASH_REMATCH[1]}"
((++fields[-1]))
(
IFS="."
printf '"%s";\n' "${fields[*]}"
)
fi
"1.0.0.0.6";
bash doesn't have an operator for assigning to a string index. So you'll need to concatenate the portions before and after the index you want to replace.
s=1.0.0.0.5
s=${s:0:8}6${s:9:}
${s:0:8} means the first 8 characters, and ${s:9:} means all the characters starting from index 9. So this replaces the character at index 8.
You can use a Bash regex:
s="1.0.0.0.5"
replacement="6"
[[ $s =~ ^(.*\.)[^.]*$ ]]
echo "${BASH_REMATCH[1]}$replacement"
Prints:
1.0.0.0.6

A bash loop to echo all possible ASCII characters [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 know how to print all letters
{a..z} and {A..Z} and {0..9}
But is there a way to print all possible ASCII Characters via a bash loop?
You don't need a loop
echo -e \\x{0..7}{{0..9},{A..F}}
It prints all chars from 0 to 127.
If it is okay to use awk:
awk 'BEGIN{for (i=32;i<127;i++) printf("%c", i)}'
Or using printf:
for((i=32;i<127;i++)) do printf "\x$(printf %x $i)"; done
use this:
for ((i=32;i<127;i++)) do printf "\\$(printf %03o "$i")"; done;printf "\n"

Get a subset of several alphabetically ordered files in Bash [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
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'}"

Substrings after 3 underscores and before a dot in Linux [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 have a some strings like below in Linux.
abc_def_fgh_2018_08_11.zip
I want to extract just 2018_08_11 as a variable. All the strings have the same pattern 3 underscores and some dates or characters and .zip
How can I do that?
Take a look at this parameter expansion:
$ foo='abc_def_fgh_2018_08_11.zip'
$ foo=${foo#*_*_*_} # remove the prefix
$ echo "${foo%.*}" # remove the sufix and print
2018_08_11
Or using regular expression:
$ foo='abc_def_fgh_2018_08_11.zip'
$ regex='^([^_]*_){3}(.*)\.'
$ [[ $foo =~ $regex ]] && echo "${BASH_REMATCH[2]}"
2018_08_11
BASH_REMATCH is a special array where the matches from [[ ... =~ ... ]] are assigned to.

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

Resources